PHXA7 programs added

This commit is contained in:
Emmanuel HC
2026-05-26 17:40:18 -05:00
parent b279912db1
commit 63b2870871
30 changed files with 1143 additions and 478 deletions

View File

@@ -10,10 +10,10 @@
[platformio]
default_envs = CRAH_UMAS_TCP ; Select here the name of the configuration you want to download
default_envs = CRAH_TxAir_BASX_TCP_PHXA7 ; Select here the name of the configuration you want to download
[env]
upload_port = COM11
upload_port = COM12
[common_env_options]
framework = arduino
@@ -275,3 +275,28 @@ board = dfrobot_firebeetle2_esp32e
extends = common_env_options
build_flags = -D USE_MODBUS_IP
build_src_filter = -<*> +<BMS/STU/STU_UMP_STU_2_0_CAH_IDR_60_TCP_PHXA7>
[env:Harmonic_Guard_RTU_PHXA7]
platform = espressif32
board = dfrobot_firebeetle2_esp32e
extends = common_env_options
build_src_filter = -<*> +<EPMS/Harmonic_Filter/Harmonic_Guard_RTU_PHXA7>
[env:GEN_Kohler_KD2500_RTU_PHXA7]
platform = espressif32
board = dfrobot_firebeetle2_esp32e
extends = common_env_options
build_src_filter = -<*> +<EPMS/GEN/GEN_Kohler_KD2500_RTU_PHXA7>
[env:VFD_YASKAWA_HV600_RTU_PHXA7]
platform = espressif32
board = dfrobot_firebeetle2_esp32e
extends = common_env_options
build_src_filter = -<*> +<BMS/VFD/VFD_YASKAWA_HV600_RTU_PHXA7>
[env:CRAH_TxAir_BASX_TCP_PHXA7]
platform = espressif32
board = dfrobot_firebeetle2_esp32e
extends = common_env_options
build_flags = -D USE_MODBUS_IP
build_src_filter = -<*> +<BMS/CRAH/CRAH_TxAir_BASX_TCP_PHXA7>

View File

@@ -14,6 +14,7 @@
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "Strategies/Strategy_SingleValue.h"
#include "Strategies/Strategy_Saw.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
@@ -31,8 +32,50 @@
*/
template<>
StandbyState<ModbusRTU>::StandbyState() {
addStrategy("Sts_EvapHeater", new SingleValueStrategy(100.0f, 5.0f, 1000));
addStrategy("Sts_EvapHeater", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Sts_EvapPump", new SawStrategy(100.0f, 1000.0f, 13.0f, 1000));
addStrategy("Sts_FlowSwitch", new SawStrategy(100.0f, 1000.0f, 14.0f, 1000));
addStrategy("Sts_AmbientTemp", new SawStrategy(100.0f, 1000.0f, 15.0f, 1000));
addStrategy("Sts_EvapTempIN", new SawStrategy(100.0f, 1000.0f, 16.0f, 1000));
addStrategy("Sts_EvapTempOUT", new SawStrategy(100.0f, 1000.0f, 17.0f, 1000));
addStrategy("Sts_VSD_Cmd_Hz", new SawStrategy(100.0f, 1000.0f, 18.0f, 1000));
addStrategy("Sts_VSD_FdbkHz", new SawStrategy(100.0f, 1000.0f, 19.0f, 1000));
addStrategy("Sts_Cond1Temp", new SawStrategy(100.0f, 1000.0f, 18.0f, 1000));
addStrategy("StS_Cond1FanSpd", new SawStrategy(100.0f, 1000.0f, 17.0f, 1000));
addStrategy("Sts_Cond2Temp", new SawStrategy(100.0f, 1000.0f, 16.0f, 1000));
addStrategy("Sts_Cond2FanSpd", new SawStrategy(100.0f, 1000.0f, 15.0f, 1000));
addStrategy("Sts_Comp1", new SawStrategy(100.0f, 1000.0f, 14.0f, 1000));
addStrategy("Sts_Comp1_DischargePressure", new SawStrategy(100.0f, 1000.0f, 13.0f, 1000));
addStrategy("Sts_Comp1_SuctionPressure", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Sts_Comp1_FLA", new SawStrategy(100.0f, 1000.0f, 11.0f, 1000));
addStrategy("Sts_Comp1Starts", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Sts_Comp2", new SawStrategy(100.0f, 1000.0f, 13.0f, 1000));
addStrategy("Sts_Comp2_DischargePressure", new SawStrategy(100.0f, 1000.0f, 14.0f, 1000));
addStrategy("Sts_Comp2_SuctionPressure", new SawStrategy(100.0f, 1000.0f, 15.0f, 1000));
addStrategy("Sts_Comp2_FLA", new SawStrategy(100.0f, 1000.0f, 16.0f, 1000));
addStrategy("Sts_Comp2Starts", new SawStrategy(100.0f, 1000.0f, 17.0f, 1000));
addStrategy("Sts_Sys1_DischPress", new SawStrategy(100.0f, 1000.0f, 18.0f, 1000));
addStrategy("Sts_Sys1_SuctPress", new SawStrategy(100.0f, 1000.0f, 19.0f, 1000));
addStrategy("Sts_Sys1_DischTemp", new SawStrategy(100.0f, 1000.0f, 18.0f, 1000));
addStrategy("Sts_Sys1_OilPress", new SawStrategy(100.0f, 1000.0f, 17.0f, 1000));
addStrategy("Sts_Sys1_EconValvePos", new SawStrategy(100.0f, 1000.0f, 16.0f, 1000));
addStrategy("Sts_Sys1_EductorTemp", new SawStrategy(100.0f, 1000.0f, 15.0f, 1000));
addStrategy("Sts_Sys1_MotorTemp", new SawStrategy(100.0f, 1000.0f, 14.0f, 1000));
addStrategy("Sts_Sys1_Runtime", new SawStrategy(100.0f, 1000.0f, 13.0f, 1000));
addStrategy("Sts_Sys1_FankW", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Sts_Sys1_CompkW", new SawStrategy(100.0f, 1000.0f, 11.0f, 1000));
addStrategy("Sts_Sys2_DischPress", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Sts_Sys2_SuctPress", new SawStrategy(100.0f, 1000.0f, 13.0f, 1000));
addStrategy("Sts_Sys2_DischTemp", new SawStrategy(100.0f, 1000.0f, 14.0f, 1000));
addStrategy("Sts_Sys2_OilPress", new SawStrategy(100.0f, 1000.0f, 15.0f, 1000));
addStrategy("Sts_Sys2_EconValvePos", new SawStrategy(100.0f, 1000.0f, 16.0f, 1000));
addStrategy("Sts_Sys2_EductorTemp", new SawStrategy(100.0f, 1000.0f, 17.0f, 1000));
addStrategy("Sts_Sys2_MotorTemp", new SawStrategy(100.0f, 1000.0f, 18.0f, 1000));
addStrategy("Sts_Sys2_Runtime", new SawStrategy(100.0f, 1000.0f, 19.0f, 1000));
addStrategy("Sts_Sys2_FankW", new SawStrategy(100.0f, 1000.0f, 18.0f, 1000));
addStrategy("Sts_Sys2_CompkW", new SawStrategy(100.0f, 1000.0f, 14.0f, 1000));
}
/**
* @brief Executes the standby state's logic for one update cycle.

View File

@@ -40,7 +40,7 @@
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
const int MODBUS_ID = 6; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
@@ -54,57 +54,57 @@
*/
modbusMap mb_map[] =
{
{HR, 67, 0, "Sts_EvapHeater"},
{HR, 68, 0, "Sts_EvapPump"},
{HR, 87, 0, "Sts_FlowSwitch"},
{HR, 10, 0, "Sts_AmbientTemp"},
{HR, 6, 0, "Sts_EvapTempIN"},
{HR, 5, 0, "Sts_EvapTempOUT"},
{HR, 127, 0, "Sts_VSD_CmdHz"},
{HR, 27, 0, "Sts_VSD_FdbkHz"},
{HR, 8, 0, "Sts_Cond1Temp"},
{HR, 120, 0, "Sts_Cond1FanSpd"},
{HR, 50, 0, "Sts_Cond2Temp"},
{HR, 121, 0, "Sts_Cond2FanSpd"},
{HR, 69, 0, "Sts_Comp1"},
{HR, 14, 0, "Sts_Comp1_DischargePresure"},
{HR, 13, 0, "Sts_Comp1_SuctionPresure"},
{HR, 15, 0, "Sts_Comp1_FLA"},
{HR, 17, 0, "Sts_Comp1Starts"},
{HR, 70, 0, "Sts_Comp2"},
{HR, 23, 0, "Sts_Comp2_DischargePresure"},
{HR, 22, 0, "Sts_Comp2_SuctionPresure"},
{HR, 24, 0, "Sts_Comp2_FLA"},
{HR, 26, 0, "Sts_Comp2Starts"},
{HR, 14, 0, "Sts_Sys1_DischPress"},
{HR, 13, 0, "Sts_Sys1_SuctPress"},
{HR, 9, 0, "Sts_Sys1_DischTemp"},
{HR, 12, 0, "Sts_Sys1_OilPress"},
{HR, 42, 0, "Sts_Sys1_EconValvePos"},
{HR, 11, 0, "Sts_Sys1_EductorTemp"},
{HR, 18, 0, "Sts_Sys1_MotorTemp"},
{HR, 30, 0, "Sts_Sys1_OpCode"},
{HR, 31, 0, "Sts_Sys1_FaultCode"},
{HR, 16, 0, "Sts_Sys1_Runtime"},
{HR, 141, 0, "Sts_Sys1_FanKW"},
{HR, 142, 0, "Sts_Sys1_CompKW"},
{HR, 66, 0, "Sts_EvapHeater"},
{HR, 67, 0, "Sts_EvapPump"},
{HR, 86, 0, "Sts_FlowSwitch"},
{HR, 9, 0, "Sts_AmbientTemp"},
{HR, 5, 0, "Sts_EvapTempIN"},
{HR, 4, 0, "Sts_EvapTempOUT"},
{HR, 126, 0, "Sts_VSD_CmdHz"},
{HR, 26, 0, "Sts_VSD_FdbkHz"},
{HR, 7, 0, "Sts_Cond1Temp"},
{HR, 119, 0, "Sts_Cond1FanSpd"},
{HR, 49, 0, "Sts_Cond2Temp"},
{HR, 120, 0, "Sts_Cond2FanSpd"},
{HR, 68, 0, "Sts_Comp1"},
{HR, 13, 0, "Sts_Comp1_DischargePresure"},
{HR, 12, 0, "Sts_Comp1_SuctionPresure"},
{HR, 14, 0, "Sts_Comp1_FLA"},
{HR, 16, 0, "Sts_Comp1Starts"},
{HR, 69, 0, "Sts_Comp2"},
{HR, 22, 0, "Sts_Comp2_DischargePresure"},
{HR, 21, 0, "Sts_Comp2_SuctionPresure"},
{HR, 23, 0, "Sts_Comp2_FLA"},
{HR, 25, 0, "Sts_Comp2Starts"},
{HR, 13, 0, "Sts_Sys1_DischPress"},
{HR, 12, 0, "Sts_Sys1_SuctPress"},
{HR, 8, 0, "Sts_Sys1_DischTemp"},
{HR, 11, 0, "Sts_Sys1_OilPress"},
{HR, 41, 0, "Sts_Sys1_EconValvePos"},
{HR, 10, 0, "Sts_Sys1_EductorTemp"},
{HR, 17, 0, "Sts_Sys1_MotorTemp"},
{HR, 29, 0, "Sts_Sys1_OpCode"},
{HR, 30, 0, "Sts_Sys1_FaultCode"},
{HR, 15, 0, "Sts_Sys1_Runtime"},
{HR, 140, 0, "Sts_Sys1_FankW"},
{HR, 142, 0, "Sts_Sys1_CompkW"},
{HR, 23, 0, "Sts_Sys2_DischPress"},
{HR, 22, 0, "Sts_Sys2_SuctPress"},
{HR, 51, 0, "Sts_Sys2_DischTemp"},
{HR, 21, 0, "Sts_Sys2_OilPress"},
{HR, 43, 0, "Sts_Sys2_EconValvePos"},
{HR, 20, 0, "Sts_Sys2_EductorTemp"},
{HR, 19, 0, "Sts_Sys2_MotorTemp"},
{HR, 32, 0, "Sts_Sys2_OpCode"},
{HR, 33, 0, "Sts_Sys2_FaultCode"},
{HR, 25, 0, "Sts_Sys2_Runtime"},
{HR, 143, 0, "Sts_Sys2_FanKW"},
{HR, 144, 0, "Sts_Sys2_CompKW"},
{HR, 66, 0, "Alm_Summary"},
{HR, 85, 0, "Alm_Sys1_Lockout"},
{HR, 86, 0, "Alm_Sys2_Lockout"},
{HR, 175, 0, "Alm_Cond1_FanFlt"},
{HR, 176, 0, "Alm_Cond2_FanFlt"},
{HR, 50, 0, "Sts_Sys2_DischTemp"},
{HR, 20, 0, "Sts_Sys2_OilPress"},
{HR, 42, 0, "Sts_Sys2_EconValvePos"},
{HR, 19, 0, "Sts_Sys2_EductorTemp"},
{HR, 18, 0, "Sts_Sys2_MotorTemp"},
{HR, 31, 0, "Sts_Sys2_OpCode"},
{HR, 32, 0, "Sts_Sys2_FaultCode"},
{HR, 24, 0, "Sts_Sys2_Runtime"},
{HR, 142, 0, "Sts_Sys2_FankW"},
{HR, 143, 0, "Sts_Sys2_CompkW"},
{HR, 65, 0, "Alm_Summary"},
{HR, 84, 0, "Alm_Sys1_Lockout"},
{HR, 85, 0, "Alm_Sys2_Lockout"},
{HR, 174, 0, "Alm_Cond1_FanFlt"},
{HR, 175, 0, "Alm_Cond2_FanFlt"},
};
//Size of modbus map used in FOR cycles, automatically calculated.

View File

@@ -0,0 +1,33 @@
# EQUIPMENT_TYPE MANUFACTURER MODEL TCP
## Brief Introduction
Equipment specifc details that make it different from other devices
## List of Equipmentt
This cofiguration has been used for these models:
* **Model**: 09-15-22
* **Model**: 09-15-23
* **Model**: 09-15-25
## Hardware Prerequisites
The code is written for an ESP8266/ESP32-style microcontroller with WiFi capabilities.
* **Microcontroller**: [Firebeetle 2 ESP32.](https://www.dfrobot.com/product-2231.html)
---
## States and Strategies
Provide a brief description of what variables and strategies were used in this configuraiton
### Standby State
* **Equipment running**: set to 0
* **Common Alarm**: set to 0
* **SAT temperature**: set to 85
### Running State
* **Equipment running**: set to 1
* **SAT temperature**: **Ramp Strategy** set to 65 deg setpoint
### Fail State
* **Commong Alarm**: set to 1
* **SAT temperature**: **Ramp Strategy** set to 105 deg setpointset

View File

@@ -0,0 +1,81 @@
/**
* @file State_Fail.cpp
* @brief Implementation of the FailState class.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-05
*
* This file contains the implementation for the FailState, which defines
* the behavior of the equipment when it has entered a fault condition.
*/
#include "ModbusPoints/Modbus_Point.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "Strategies/Strategy_SingleValue.h"
#include "Strategies/Strategy_PID.h"
#include "States/State_Standby.h"
#include "States/State_Running.h"
#include "States/State_Fail.h"
#if defined(USE_MODBUS_IP)
#include <ModbusIP_ESP8266.h>
#else
#include <ModbusRTU.h>
#endif
/**
* @brief Constructs a new FailState object with a list of active alarms.
*
* This constructor receives a list of alarm descriptions and creates strategies
* to set the corresponding Modbus points to a value of 1, indicating an
* active alarm. It also initializes a PID strategy for the 'CW Valve Position'
* to maintain its state during the fault.
* @param activeAlarms A vector of strings, where each string is the
* description of a Modbus point to be set as an active alarm.
*/
template<>
FailState<ModbusIP>::FailState(const std::vector<std::string>& activeAlarms) {
// Simulate a failure: set common alarm and a specific fan alarm.
}
/**
* @brief Executes the fail state's logic for one update cycle.
*
* This method checks the "Alarm Reset" Modbus point for a command to
* transition back to Standby, which would typically happen after a fault
* is cleared by a user. If no transition is requested, it continues to apply
* the failure strategies (e.g., keeping alarm bits active).
*
* @param equipment Pointer to the Equipment instance.
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
*/
template<>
State<ModbusIP>* FailState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
// STATE control, add conditions if change to a different state is needed
Serial.println("Fail update function");
_applyStrategies(equipment);
return nullptr;
}
/**
* @brief Logic to execute once when entering the fail state.
* Sets the "Alarm Common" point to 1 to indicate a general fault condition.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void FailState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
// Logic to run when the equipment enters this state
Serial.println("Enter Fail State...");
}
/**
* @brief Logic to execute once when exiting the fail state.
* Clears the "Alarm Common" point to 0 before transitioning to the next state.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void FailState<ModbusIP>::exitState(Equipment<ModbusIP>* equipment) {
// Cleanup logic to run when the equipment leaves this state
Serial.println("Exit Fail State...");
}

View File

@@ -0,0 +1,89 @@
/**
* @file State_Running.cpp
* @brief Implementation of the RunningState class.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-05
*
* This file contains the implementation for the RunningState, which defines
* the behavior of the equipment when it is actively running.
*/
#include "ModbusPoints/Modbus_Point.h"
#include "ModbusPoints/Modbus_FloatDecorator.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "Strategies/Strategy_Random.h"
#include "Strategies/Strategy_Saw.h"
#include "Strategies/Strategy_SingleValue.h"
#include "Strategies/Strategy_Square.h"
#include "Strategies/Strategy_PID.h"
#include "Strategies/Strategy_Totalizer.h"
#include "States/State_Standby.h"
#include "States/State_Running.h"
#include "States/State_Fail.h"
#include "States/State.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
#include <ModbusIP_ESP8266.h>
#else
#include <ModbusRTU.h>
#endif
/**
* @brief Constructs a new RunningState object.
*
* This constructor initializes behavior strategies active during the running
* state, such as a PID controller for the 'CW Valve Position' and totalizers
* for the run-hours of each EC fan.
*/
template<>
RunningState<ModbusIP>::RunningState() {
}
/**
* @brief Executes the running state's logic for one update cycle.
*
* This method first checks for state transition commands:
* 1. It reads the "ON/OFF Command By BMS" point. If it's 0, it transitions to StandbyState.
* 2. It reads the "Fault Code" point. If it's non-zero, it transitions to FailState,
* passing the corresponding alarm description.
*
* If no transition occurs, it applies the strategies defined for the running state.
*
* @param equipment Pointer to the Equipment instance.
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
*/
template<>
State<ModbusIP>* RunningState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
// STATE control, add conditions if change to a different state is needed
Serial.println("Running update function");
// Apply any strategies defined for the standby state
_applyStrategies(equipment);
return nullptr;
}
/**
* @brief Logic to execute once when entering the running state.
* Sets the "Run Status" for all EC fans to 1 to indicate they are active.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void RunningState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
// Logic to run when the equipment enters this state
Serial.println("Enter Running State...");
// You could also update a Modbus register to show the "standby" state
}
/**
* @brief Logic to execute once when exiting the running state.
* Sets the "Run Status" for all EC fans to 0 before transitioning to the next state.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void RunningState<ModbusIP>::exitState(Equipment<ModbusIP>* equipment) {
// Cleanup logic to run when the equipment leaves this state
Serial.println("Exit Running State...");
}

View File

@@ -0,0 +1,100 @@
/**
* @file State_Standby.cpp
* @brief Implementation of the StandbyState class.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-05
*
* This file contains the implementation for the StandbyState, which defines
* the behavior of the equipment when it is in an idle or standby mode.
*/
#include "ModbusPoints/Modbus_Point.h"
#include "ModbusPoints/Modbus_FloatDecorator.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "Strategies/Strategy_Random.h"
#include "Strategies/Strategy_Saw.h"
#include "Strategies/Strategy_SingleValue.h"
#include "Strategies/Strategy_Square.h"
#include "Strategies/Strategy_PID.h"
#include "States/State_Standby.h"
#include "States/State_Running.h"
#include "States/State_Fail.h"
#include "States/State.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
#include <ModbusIP_ESP8266.h>
#else
#include <ModbusRTU.h>
#endif
/**
* @brief Constructs a new StandbyState object.
*
* In this state, the equipment is idle. This constructor initializes strategies
* to bring the system to a safe, idle condition. It sets a stable value for
* the SAT reading and creates ramp strategies to bring the CW valve and all
* EC fan speeds down to zero.
*/
template<>
StandbyState<ModbusIP>::StandbyState() {
// You can add initialization code here if needed
addStrategy("Cool_PID_Demand", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SAT", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("RAT", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("RAH", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Plenum_DP", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("CCV_Fdbk", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("CCV_Cmd", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Active_SAT_SP", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Active_SF_Spd_Cmd", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SF1_Fbk", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SF2_Fbk", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SF1_Pwr", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SF2_Pwr", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("RAT_PID_OUT", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SF1_Fbk_Percent_Supply", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("SF2_Fbk_Percent_Supply", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
addStrategy("Run_Hours", new SawStrategy(100.0f, 1000.0f, 12.0f, 1000));
}
/**
* @brief Executes the standby state's logic for one update cycle.
*
* This method applies the strategies defined for the standby state (e.g.,
* ramping values to zero).
*
* @warning This method currently does not check for a command to transition to the
* Running state. This logic needs to be added to allow the unit to start.
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
*/
template<>
State<ModbusIP>* StandbyState<ModbusIP>::update(Equipment<ModbusIP>* equipment) {
// STATE control, add conditions if change to a different state is needed
Serial.println("Standby update function");
// Apply any strategies defined for the standby state
_applyStrategies(equipment);
return nullptr;
}
/**
* @brief Logic to execute once when entering the standby state.
* This method performs cleanup by setting all alarm points and all EC fan
* run status points to 0.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void StandbyState<ModbusIP>::enterState(Equipment<ModbusIP>* equipment) {
// Logic to run when the equipment enters this state
Serial.println("Enter Standby State...");
}
/**
* @brief Logic to execute once when exiting the standby state.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void StandbyState<ModbusIP>::exitState(Equipment<ModbusIP>* equipment) {
// Cleanup logic to run when the equipment leaves this state
Serial.println("Exit Standby State...");
}

View File

@@ -0,0 +1,151 @@
/**
* @file config.h
* @brief Main configuration file for the CRAH Unit (TCP) emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* This file contains two important configurations: WiFi network parameters
* and the Modbus register map for the device.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "core.h"
#include "Equipment/Equipment.h"
#if defined(USE_MODBUS_IP)
/**
* @defgroup ModbusTCPConfig Modbus IP Configuration
* @brief Parameters for Modbus TCP communication.
* @{
*/
#include <ModbusIP_ESP8266.h>
const char *ssid = "PHXA7"; /**< @brief The SSID of the WiFi network. */
const char *password = "password"; /**< @brief The password for the WiFi network. */
IPAddress local_IP(172, 17, 40, 25); /**< @brief The static IP address for the device. */
IPAddress gateway(172, 17, 40, 1); /**< @brief The gateway IP address. */
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
ModbusIP mb;
#else
/**
* @defgroup ModbusRTUConfig Modbus RTU Configuration
* @brief Parameters for serial Modbus RTU communication.
* @{
*/
#include <ModbusRTU.h>
const int BAUDRATE = 19200; /**< @brief The serial communication speed in bits per second. */
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
ModbusRTU mb;
#endif
/**
* @defgroup ModbusMapConfig Modbus Map Configuration
* @brief Defines the Modbus register map and related parameters for the emulator.
* @{
*/
/**
* @brief The Modbus map for the Equipment device.
* This array defines all the Modbus points available on the emulated device.
* The `description` field is crucial as it's used to look up points within the application logic.
*/
modbusMap mb_map[] =
{
{COIL, 0, 0, "BMS_OnOff"},
{COIL, 1, 0, "Alm_reset"},
{COIL, 2, 0, "BMS_HB"},
{COIL, 3, 0, "BMS_CCV_Ovrride"},
{COIL, 4, 0, "BMD_SF_Override"},
{COIL, 6, 0, "BMS_Monitor_Disabled"},
{DI, 0, 0, "Alm_General"},
{DI, 1, 0, "Sensor_Fault"},
{DI, 2, 0, "PLC_HB"},
{DI, 3, 0, "SF_Start_Cmd"},
{DI, 4, 0, "SF_Proven"},
{DI, 5, 0, "SF1_Running"},
{DI, 6, 0, "SF2_Running"},
{DI, 7, 0, "Cool_Allowed"},
{DI, 8, 0, "Alm_BMS_Lost"},
{DI, 9, 0, "Alm_Ext_Intlk"},
{DI, 10, 0, "Alm_Hi_Static"},
{DI, 11, 0, "Alm_Leak"},
{DI, 12, 0, "Alm_Pump"},
{DI, 13, 0, "Alm_Filter"},
{DI, 14, 0, "Alm_CCV_Pos"},
{DI, 15, 0, "Alm_Hi_SAT"},
{DI, 16, 0, "Alm_Low_SAT"},
{DI, 17, 0, "Alm_Hi_RAT"},
{DI, 18, 0, "Alm_Low_RAT"},
{DI, 19, 0, "Alm_Hi_RAH"},
{DI, 20, 0, "Alm_Low_RAH"},
{DI, 21, 0, "SF1_Fault"},
{DI, 22, 0, "SF2_Fault"},
{DI, 23, 0, "SF1_Offline"},
{DI, 24, 0, "SF2_Offline"},
{DI, 25, 0, "SF1_ECM_Proof"},
{DI, 26, 0, "SF2_ECM_Proof"},
{DI, 27, 0, "SF1_Dir_Supply"},
{DI, 28, 0, "SF2_Dir_Supply"},
{DI, 29, 0, "Condensate_Pump_Running"},
{HR, 0, 0, "BMS_CCV_Pos"},
{HR, 1, 0, "BMS_SAT_SP"},
{HR, 2, 0, "BMS_SF_Speed_cmd"},
{HR, 3, 0, "BMS_Timeout"},
{HR, 4, 0, "CCV_alm_Delay_Cooling"},
{HR, 5, 0, "CCV_alm_Pos_Cooling"},
{HR, 6, 0, "CCV_Startup_Pos_Cooling"},
{HR, 7, 0, "CCV_Startup_Time_Cooling"},
{HR, 8, 0, "Hi_RAH_SP"},
{HR, 9, 0, "Hi_RAT_SP"},
{HR, 10, 0, "Hi_SAT_SP"},
{HR, 11, 0, "Low_RAH_SP"},
{HR, 12, 0, "Low_RAT_SP"},
{HR, 13, 0, "Low_SAT_SP"},
{HR, 14, 0, "Hum_Alm_Delay"},
{HR, 15, 0, "SF_Startup_SPD"},
{HR, 16, 0, "SF_Startup_Time"},
{HR, 17, 0, "Temp_Alm_Delay"},
{HR, 18, 0, "RAT_SP"},
{IR, 0, 0, "Cool_PID_Demand"},
{IR, 1, 0, "SAT"},
{IR, 2, 0, "RAT"},
{IR, 3, 0, "RAH"},
{IR, 4, 0, "Plenum_DP"},
{IR, 5, 0, "CCV_Fdbk"},
{IR, 6, 0, "CCV_Cmd"},
{IR, 8, 0, "Active_SAT_SP"},
{IR, 9, 0, "Active_SF_Spd_Cmd"},
{IR, 10, 0, "SF_SPD_CMD"},
{IR, 11, 0, "SF1_Fbk"},
{IR, 12, 0, "SF2_Fbk"},
{IR, 13, 0, "SF1_Pwr"},
{IR, 14, 0, "SF2_Pwr"},
{IR, 15, 0, "SF1_Fault"},
{IR, 16, 0, "SF2_Fault"},
{IR, 17, 0, "RAT_PID_OUT"},
{IR, 18, 0, "SF1_Fbk_Percen_Supply"},
{IR, 19, 0, "SF2_Fbk_Percen_Supply"},
{IR, 20, 0, "Run_Hours"},
};
//Size of modbus map used in FOR cycles, automatically calculated.
/**
* @brief The total number of entries in the `mb_map` array.
* This is calculated at compile time and used for iterating over the map.
*/
const int map_size = sizeof(mb_map) / sizeof(mb_map[0]);
/** @brief The main loop update interval in milliseconds. */
int interval = 250;
/** @} */ // End of ModbusMapConfig group
#endif // CONFIG_H

View File

@@ -0,0 +1,86 @@
/**
* @file main.cpp
* @brief Main execution program for the CRAH Unit (TCP) Emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* @details This file contains the main execution program for an Arduino-based emulator of a CRAH unit.
* The program uses a Wi-Fi connection to communicate via the Modbus IP protocol.
*
* The setup() function initializes the following:
* - Serial communication for debugging.
* - Wi-Fi connection using credentials from config.h.
* - A Modbus TCP server.
* - Modbus points (Coils, Holding Registers, etc.) based on a predefined map in config.h.
*
* The loop() function continuously:
* - Services the Modbus TCP server to handle incoming requests.
* - Periodically calls the main update loop for the emulated equipment, which
* manages state transitions and behavior strategies.
*
* @see config.h for Wi-Fi and Modbus configuration.
* @see Equipment.h for the main equipment logic.
* @see State.h for different equipment states.
* @see Strategies/Strategy_Behavior.h for value generation strategies.
* @see Modbus_Point.h for the base class for all Modbus points.
*/
//=================================================================================================================================
//Libraries and declaration of variables.
#include <WiFi.h>
#include "config.h"
#include "ModbusPoints/Modbus_PointFactory.h"
#if defined(USE_MODBUS_IP)
#include <ModbusIP_ESP8266.h>
#else
#include <ModbusRTU.h>
#endif
//=================================================================================================================================
/**
* @brief Initializes the application.
* @details This function runs once at startup. It configures the serial communication,
* Wi-Fi, and the Modbus server. It also creates and initializes all the Modbus points
* based on the `mb_map` array in `config.h`.
*/
void setup() {
Serial.begin(115200); //Serial comm start
WiFi.config(local_IP, gateway, subnet); // Wifi service start
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected!!");
mb.server(); //Modbus server start
Serial.println("Server Created");
Serial.println(map_size);
for(int i = 0; i < map_size; i++){
Modbus_Point<ModbusIP>* point = createModbus_Point(&mb, mb_map[i].category, mb_map[i].address, mb_map[i].value, mb_map[i].description);
if (point) {
point->addToModbusServer();
EquipmentInstance.addModbus_Point(mb_map[i].description, point);
}
}
Serial.println("All modbus Points created");
Serial.println("Setup function ended");
}
//=================================================================================================================================
/**
* @brief The main application loop.
* @details This function runs repeatedly after setup() has completed. It performs two main actions:
* 1. It continuously services the Modbus server by calling `mb.task()` to handle
* incoming requests from a Modbus master.
* 2. At a fixed interval (defined in `config.h`), it calls `EquipmentInstance.update()`
* to run the emulator's internal state machine and behavior logic.
*/
void loop() {
mb.task();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
unsigned long startTime = millis();
EquipmentInstance.update();
unsigned long endTime = millis();
unsigned long elapsedTime = endTime - startTime;
Serial.printf("Control Execution time: %d ms\n", elapsedTime);
}
}

View File

@@ -13,7 +13,8 @@
#include "ModbusPoints/Modbus_FloatDecorator.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "Strategies/Strategy_SingleValue.h"
#include "Strategies/Strategy_Saw.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
@@ -31,7 +32,11 @@
*/
template<>
StandbyState<ModbusRTU>::StandbyState() {
addStrategy("Sts_SpdRPM", new SawStrategy(2500.0f, 3500.0f, 10.0f, 1000));
addStrategy("Sts_Power", new SawStrategy(15000.0f, 23000.0f, 170.0f, 1000));
addStrategy("Sts_Current", new SawStrategy(2500.0f, 3500.0f, 10.0f, 1000));
addStrategy("Sts_Voltage", new SingleValueStrategy(4800.0f, 5.0f,1000));
addStrategy("Sts_Energy", new SingleValueStrategy(18000.0f, 500.0f,1000));
}
/**

View File

@@ -40,7 +40,7 @@
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
const int MODBUS_ID = 106; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
@@ -54,16 +54,14 @@
*/
modbusMap mb_map[] =
{
{HR, 32, 0, "Sts_Remote"},
{HR, 62, 0, "Sts_SpdRPM"},
{HR, 39, 0, "Sts_Power"},
{HR, 38, 0, "Sts_Current"},
{HR, 37, 0, "Sts_Voltage"},
{HR_LONG, 92, 0, "Sts_Energy"},
{HR, 1, 0, "Cmd_Reset"},
{HR, 32, 0, "Alm_NotAuto"},
{HR, 77, 0, ""},
{HR, 91, 0, ""},
{HR, 31, 0, "Sts_Remote"},
{HR, 61, 0, "Sts_SpdRPM"},
{HR, 38, 0, "Sts_Power"},
{HR, 37, 0, "Sts_Current"},
{HR, 36, 0, "Sts_Voltage"},
{HR_LONG, 91, 0, "Sts_Energy"},
{HR, 0, 0, "Cmd_Reset"},
{HR, 31, 0, "Alm_NotAuto"},
};
//Size of modbus map used in FOR cycles, automatically calculated.

View File

@@ -1,164 +0,0 @@
/**
* @file config.h
* @brief Main configuration file for the Daikin Chiller (RTU) emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* This file contains important configurations for the Modbus RTU communication
* and the specific register map for the emulated device.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <ModbusRTU.h>
#include "core.h"
#include "Equipment/Equipment.h"
#if defined(USE_MODBUS_IP)
/**
* @defgroup ModbusTCPConfig Modbus IP Configuration
* @brief Parameters for Modbus TCP communication.
* @{
*/
#include <ModbusIP_ESP8266.h>
const char *ssid = "wifi_name"; /**< @brief The SSID of the WiFi network. */
const char *password = "wifi_password"; /**< @brief The password for the WiFi network. */
IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */
IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
ModbusIP mb;
#else
/**
* @defgroup ModbusRTUConfig Modbus RTU Configuration
* @brief Parameters for serial Modbus RTU communication.
* @{
*/
#include <ModbusRTU.h>
const int BAUDRATE = 19200; /**< @brief The serial communication speed in bits per second. */
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
ModbusRTU mb;
#endif
/**
* @brief The Modbus map for the Equipment device.
* This array defines all the Modbus points available on the emulated device.
* The `description` field is crucial as it's used to look up points within the application logic.
*/
modbusMap mb_map[] =
{
{COIL, 24, 0, "Alm_GenFault"},
{HR_LONG, 669, 0, "Avg_Current"},
{HR_LONG, 673, 0, "Batt_V"},
{HR_LONG, 261, 0, "Cooling_Tmp"},
{HR_LONG, 257, 0, "Engine_RPM"},
{HR_LONG, 21, 0, "Freq"},
{HR_LONG, 255, 0, "Fuel_Rate"},
{HR_LONG, 657, 0, "kVAR_Total"},
{HR_LONG, 655, 0, "kW_Total"},
{HR_LONG, 263, 0, "Manifold_Tmp"},
{HR_LONG, 279, 0, "Oil_Pres"},
{HR_LONG, 259, 0, "Oil_Tmp"},
{HR_LONG, 659, 0, "PF_Total"},
{HR_LONG, 7, 0, "VoltageA"},
{HR_LONG, 9, 0, "VoltageB"},
{HR_LONG, 11, 0, "VoltageC"},
{COIL, 30, 0, "Breaker_Sts"},
{COIL, 31, 0, "Tripped"},
{HR_LONG, 285, 0, "Fuel_Percent"},
{HR, 0, 0, "Engine_Starts"},
{HR_LONG, 267, 0, "Run_Hrs"},
{COIL, 219, 0, "Run_Status"},
{COIL, 223, 0, "Charger_AC_Failure"},
{COIL, 13, 0, "Emergency_Stop"},
{COIL, 327, 0, "Failure_to_Close_1"},
{COIL, 328, 0, "Failure_to_Close_2"},
{COIL, 357, 0, "Fuel_Hi_Lvl"},
{COIL, 236, 0, "Fuel_Leak_Detection"},
{COIL, 358, 0, "Fuel_Low_Lvl"},
{COIL, 6, 0, "Ground_Fault"},
{COIL, 227, 0, "Hi_Engine_Tmp"},
{COIL, 221, 0, "Low_Batt_V"},
{COIL, 740, 0, "Low_Coolant_Lvl"},
{COIL, 225, 0, "Low_Oil_Pres"},
{COIL, 234, 0, "Not_in_Auto"},
{COIL, 276, 0, "Over_Voltage_1"},
{COIL, 277, 0, "Over_Voltage_2"},
{COIL, 278, 0, "Over_Voltage_3"},
{COIL, 279, 0, "Over_Voltage_4"},
{COIL, 280, 0, "Over_Voltage_5"},
{COIL, 281, 0, "Over_Voltage_6"},
{COIL, 285, 0, "Overcurrent_1"},
{COIL, 286, 0, "Overcurrent_2"},
{COIL, 287, 0, "Overcurrent_3"},
{COIL, 235, 0, "Overload"},
{COIL, 763, 0, "Overspeed"},
{COIL, 226, 0, "Pre_Hi_Engine_Temp_Alm"},
{COIL, 224, 0, "Pre_Lo_Oil_Pres_Alm"},
{COIL, 24, 0, "Shutdown_Alarm"},
{COIL, 202, 0, "Under_Freq"},
{COIL, 264, 0, "Under_Voltage_1"},
{COIL, 265, 0, "Under_Voltage_2"},
{COIL, 266, 0, "Under_Voltage_3"},
{COIL, 267, 0, "Under_Voltage_4"},
{COIL, 268, 0, "Under_Voltage_5"},
{COIL, 269, 0, "Under_Voltage_6"},
{COIL, 210, 0, "Low_Cooling_Tmp"},
{HR_LONG, 14, 0, "CurrentA"},
{HR_LONG, 16, 0, "CurrentB"},
{HR_LONG, 18, 0, "CurrentC"},
{HR_LONG, 284, 0, "Fuel_Usage"},
{HR_LONG, 2, 0, "VoltageAB"},
{HR_LONG, 4, 0, "VoltageBC"},
{HR_LONG, 6, 0, "VoltageCA"},
{COIL, 247, 0, "ECU_CommLoss"},
{HR_LONG, 672, 0, "Controller_Hours"},
{COIL, 14, 0, "E_Stop"},
{COIL, 270, 0, "OV_Warning_1"},
{COIL, 271, 0, "OV_Warning_2"},
{COIL, 272, 0, "OV_Warning_3"},
{COIL, 273, 0, "OV_Warning_4"},
{COIL, 274, 0, "OV_Warning_5"},
{COIL, 275, 0, "OV_Warning_6"},
{COIL, 282, 0, "OC_Warning_1"},
{COIL, 283, 0, "OC_Warning_2"},
{COIL, 284, 0, "OC_Warning_3"},
{COIL, 203, 0, "Ufreq_Shutdown"},
{COIL, 258, 0, "UV_Warning_1"},
{COIL, 259, 0, "UV_Warning_2"},
{COIL, 260, 0, "UV_Warning_3"},
{COIL, 261, 0, "UV_Warning_4"},
{COIL, 262, 0, "UV_Warning_5"},
{COIL, 263, 0, "UV_Warning_6"},
{COIL, 201, 0, "Overcrank"},
{COIL, 230, 0, "Alt_Thermal_Shutdown_1"},
{COIL, 231, 0, "Alt_Thermal_Shutdown_2"},
{COIL, 232, 0, "Alt_Thermal_Shutdown_3"},
{COIL, 233, 0, "Alt_Thermal_Shutdown_4"},
{COIL, 250, 0, "RevPwr_Shutdown"},
{COIL, 251, 0, "RevVAR_Shutdown"},
{COIL, 318, 0, "Sys_NotReady"},
{COIL, 241, 0, "Week_Battery"},
};
//Size of modbus map used in FOR cycles, automatically calculated.
/**
* @brief The total number of entries in the `mb_map` array.
* This is calculated at compile time and used for iterating over the map.
*/
const int map_size = sizeof(mb_map) / sizeof(mb_map[0]);
/**
* @brief The main loop update interval in milliseconds.
*/
int interval = 250;
#endif // CONFIG_H

View File

@@ -13,7 +13,7 @@
#include "ModbusPoints/Modbus_FloatDecorator.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "strategies/Strategy_SingleValue.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
@@ -31,7 +31,29 @@
*/
template<>
StandbyState<ModbusRTU>::StandbyState() {
addStrategy("Avg_Current", new SingleValueStrategy(15000.0f, 500.0f, 1000));
addStrategy("Batt_V", new SingleValueStrategy(400.0f, 50.0f, 1000));
addStrategy("Cooling_Tmp", new SingleValueStrategy(15000.0f, 500.0f, 1000));
addStrategy("Engine_RPM", new SingleValueStrategy(15000.0f, 500.0f, 1000));
addStrategy("Freq", new SingleValueStrategy(600.0f, 5.0f, 1000));
addStrategy("Fuel_Rate", new SingleValueStrategy(15000.0f, 500.0f, 1000));
addStrategy("kVAR_Total", new SingleValueStrategy(15000.0f, 500.0f, 1000));
addStrategy("kW_Total", new SingleValueStrategy(15000.0f, 500.0f, 1000));
addStrategy("Manifold_Tmp", new SingleValueStrategy(1750.0f, 50.0f, 1000));
addStrategy("Oil_Pres", new SingleValueStrategy(1800.0f, 50.0f, 1000));
addStrategy("Oil_Tmp", new SingleValueStrategy(2300.0f, 50.0f, 1000));
addStrategy("PF_Total", new SingleValueStrategy(950.0f, 40.0f, 1000));
addStrategy("VoltageA", new SingleValueStrategy(2400.0f, 50.0f, 1000));
addStrategy("VoltageB", new SingleValueStrategy(2400.0f, 50.0f, 1000));
addStrategy("VoltageC", new SingleValueStrategy(2400.0f, 50.0f, 1000));
addStrategy("Fuel_Percent", new SingleValueStrategy(500.0f, 500.0f, 1000));
addStrategy("CurrentA", new SingleValueStrategy(1500.0f, 50.0f, 1000));
addStrategy("CurrentB", new SingleValueStrategy(1500.0f, 50.0f, 1000));
addStrategy("CurrentC", new SingleValueStrategy(1500.0f, 50.0f, 1000));
addStrategy("Fuel_Usage", new SingleValueStrategy(800.0f, 50.0f, 1000));
addStrategy("VoltageAB", new SingleValueStrategy(480.0f, 50.0f, 1000));
addStrategy("VoltageBC", new SingleValueStrategy(480.0f, 50.0f, 1000));
addStrategy("VoltageCA", new SingleValueStrategy(480.0f, 50.0f, 1000));
}
/**

View File

@@ -0,0 +1,164 @@
/**
* @file config.h
* @brief Main configuration file for the Daikin Chiller (RTU) emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* This file contains important configurations for the Modbus RTU communication
* and the specific register map for the emulated device.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <ModbusRTU.h>
#include "core.h"
#include "Equipment/Equipment.h"
#if defined(USE_MODBUS_IP)
/**
* @defgroup ModbusTCPConfig Modbus IP Configuration
* @brief Parameters for Modbus TCP communication.
* @{
*/
#include <ModbusIP_ESP8266.h>
const char *ssid = "wifi_name"; /**< @brief The SSID of the WiFi network. */
const char *password = "wifi_password"; /**< @brief The password for the WiFi network. */
IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */
IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
ModbusIP mb;
#else
/**
* @defgroup ModbusRTUConfig Modbus RTU Configuration
* @brief Parameters for serial Modbus RTU communication.
* @{
*/
#include <ModbusRTU.h>
const int BAUDRATE = 19200; /**< @brief The serial communication speed in bits per second. */
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
ModbusRTU mb;
#endif
/**
* @brief The Modbus map for the Equipment device.
* This array defines all the Modbus points available on the emulated device.
* The `description` field is crucial as it's used to look up points within the application logic.
*/
modbusMap mb_map[] =
{
{COIL, 23, 0, "Alm_GenFault"},
{HR_LONG, 668, 0, "Avg_Current"},
{HR_LONG, 672, 0, "Batt_V"},
{HR_LONG, 260, 0, "Cooling_Tmp"},
{HR_LONG, 256, 0, "Engine_RPM"},
{HR_LONG, 20, 0, "Freq"},
{HR_LONG, 254, 0, "Fuel_Rate"},
{HR_LONG, 656, 0, "kVAR_Total"},
{HR_LONG, 654, 0, "kW_Total"},
{HR_LONG, 262, 0, "Manifold_Tmp"},
{HR_LONG, 278, 0, "Oil_Pres"},
{HR_LONG, 258, 0, "Oil_Tmp"},
{HR_LONG, 658, 0, "PF_Total"},
{HR_LONG, 6, 0, "VoltageA"},
{HR_LONG, 8, 0, "VoltageB"},
{HR_LONG, 10, 0, "VoltageC"},
{COIL, 29, 0, "Breaker_Sts"},
{COIL, 30, 0, "Tripped"},
{HR_LONG, 284, 0, "Fuel_Percent"},
{HR, 999, 0, "Engine_Starts"},
{HR_LONG, 266, 0, "Run_Hrs"},
{COIL, 218, 0, "Run_Status"},
{COIL, 222, 0, "Charger_AC_Failure"},
{COIL, 12, 0, "Emergency_Stop"},
{COIL, 326, 0, "Failure_to_Close_1"},
{COIL, 327, 0, "Failure_to_Close_2"},
{COIL, 356, 0, "Fuel_Hi_Lvl"},
{COIL, 235, 0, "Fuel_Leak_Detection"},
{COIL, 357, 0, "Fuel_Low_Lvl"},
{COIL, 5, 0, "Ground_Fault"},
{COIL, 226, 0, "Hi_Engine_Tmp"},
{COIL, 220, 0, "Low_Batt_V"},
{COIL, 739, 0, "Low_Coolant_Lvl"},
{COIL, 224, 0, "Low_Oil_Pres"},
{COIL, 233, 0, "Not_in_Auto"},
{COIL, 275, 0, "Over_Voltage_1"},
{COIL, 276, 0, "Over_Voltage_2"},
{COIL, 277, 0, "Over_Voltage_3"},
{COIL, 278, 0, "Over_Voltage_4"},
{COIL, 279, 0, "Over_Voltage_5"},
{COIL, 280, 0, "Over_Voltage_6"},
{COIL, 284, 0, "Overcurrent_1"},
{COIL, 285, 0, "Overcurrent_2"},
{COIL, 286, 0, "Overcurrent_3"},
{COIL, 234, 0, "Overload"},
{COIL, 762, 0, "Overspeed"},
{COIL, 225, 0, "Pre_Hi_Engine_Temp_Alm"},
{COIL, 223, 0, "Pre_Lo_Oil_Pres_Alm"},
{COIL, 23, 0, "Shutdown_Alarm"},
{COIL, 201, 0, "Under_Freq"},
{COIL, 263, 0, "Under_Voltage_1"},
{COIL, 264, 0, "Under_Voltage_2"},
{COIL, 265, 0, "Under_Voltage_3"},
{COIL, 266, 0, "Under_Voltage_4"},
{COIL, 267, 0, "Under_Voltage_5"},
{COIL, 268, 0, "Under_Voltage_6"},
{COIL, 209, 0, "Low_Cooling_Tmp"},
{HR_LONG, 13, 0, "CurrentA"},
{HR_LONG, 15, 0, "CurrentB"},
{HR_LONG, 17, 0, "CurrentC"},
{HR_LONG, 283, 0, "Fuel_Usage"},
{HR_LONG, 1, 0, "VoltageAB"},
{HR_LONG, 3, 0, "VoltageBC"},
{HR_LONG, 5, 0, "VoltageCA"},
{COIL, 246, 0, "ECU_CommLoss"},
{HR_LONG, 671, 0, "Controller_Hours"},
{COIL, 13, 0, "E_Stop"},
{COIL, 269, 0, "OV_Warning_1"},
{COIL, 270, 0, "OV_Warning_2"},
{COIL, 271, 0, "OV_Warning_3"},
{COIL, 272, 0, "OV_Warning_4"},
{COIL, 273, 0, "OV_Warning_5"},
{COIL, 274, 0, "OV_Warning_6"},
{COIL, 281, 0, "OC_Warning_1"},
{COIL, 282, 0, "OC_Warning_2"},
{COIL, 283, 0, "OC_Warning_3"},
{COIL, 202, 0, "Ufreq_Shutdown"},
{COIL, 257, 0, "UV_Warning_1"},
{COIL, 258, 0, "UV_Warning_2"},
{COIL, 259, 0, "UV_Warning_3"},
{COIL, 260, 0, "UV_Warning_4"},
{COIL, 261, 0, "UV_Warning_5"},
{COIL, 262, 0, "UV_Warning_6"},
{COIL, 200, 0, "Overcrank"},
{COIL, 229, 0, "Alt_Thermal_Shutdown_1"},
{COIL, 230, 0, "Alt_Thermal_Shutdown_2"},
{COIL, 231, 0, "Alt_Thermal_Shutdown_3"},
{COIL, 232, 0, "Alt_Thermal_Shutdown_4"},
{COIL, 249, 0, "RevPwr_Shutdown"},
{COIL, 250, 0, "RevVAR_Shutdown"},
{COIL, 317, 0, "Sys_NotReady"},
{COIL, 240, 0, "Week_Battery"},
};
//Size of modbus map used in FOR cycles, automatically calculated.
/**
* @brief The total number of entries in the `mb_map` array.
* This is calculated at compile time and used for iterating over the map.
*/
const int map_size = sizeof(mb_map) / sizeof(mb_map[0]);
/**
* @brief The main loop update interval in milliseconds.
*/
int interval = 250;
#endif // CONFIG_H

View File

@@ -1,77 +0,0 @@
/**
* @file State_Standby.cpp
* @brief Implementation of the StandbyState class.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-05
*
* This file contains the implementation for the StandbyState, which defines
* the behavior of the equipment when it is in an idle or standby mode.
*/
#include "States/State_Running.h"
#include "States/State_Fail.h"
#include "ModbusPoints/Modbus_Point.h"
#include "ModbusPoints/Modbus_FloatDecorator.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
#include <ModbusIP_ESP8266.h>
#else
#include <ModbusRTU.h>
#endif
/**
* @brief Constructs a new StandbyState object.
*
* In this state, the equipment is idle. This constructor initializes several
* strategies to generate random values for various status points, simulating
* a live but non-operational unit.
*/
template<>
StandbyState<ModbusRTU>::StandbyState() {
}
/**
* @brief Executes the standby state's logic for one update cycle.
*
* This method checks the "Chiller On-Off" Modbus point for a command to
* transition to the Running state. If no transition is requested, it applies
* the strategies defined for the standby state.
*
* @param equipment Pointer to the Equipment instance.
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
*/
template<>
State<ModbusRTU>* StandbyState<ModbusRTU>::update(Equipment<ModbusRTU>* equipment) {
// STATE control, add conditions if change to a different state is needed
Serial.println("Standby update function");
// Apply any strategies defined for the standby state
_applyStrategies(equipment);
return nullptr;
}
/**
* @brief Logic to execute once when entering the standby state.
* Sets the "Chiller Sts" point to indicate the unit is not running.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void StandbyState<ModbusRTU>::enterState(Equipment<ModbusRTU>* equipment) {
// Logic to run when the equipment enters this state
Serial.println("Enter Standby State...");
}
/**
* @brief Logic to execute once when exiting the standby state.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void StandbyState<ModbusRTU>::exitState(Equipment<ModbusRTU>* equipment) {
// Cleanup logic to run when the equipment leaves this state
}

View File

@@ -1,169 +0,0 @@
/**
* @file config.h
* @brief Main configuration file for the Daikin Chiller (RTU) emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* This file contains important configurations for the Modbus RTU communication
* and the specific register map for the emulated device.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <ModbusRTU.h>
#include "core.h"
#include "Equipment/Equipment.h"
#if defined(USE_MODBUS_IP)
/**
* @defgroup ModbusTCPConfig Modbus IP Configuration
* @brief Parameters for Modbus TCP communication.
* @{
*/
#include <ModbusIP_ESP8266.h>
const char *ssid = "wifi_name"; /**< @brief The SSID of the WiFi network. */
const char *password = "wifi_password"; /**< @brief The password for the WiFi network. */
IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */
IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
ModbusIP mb;
#else
/**
* @defgroup ModbusRTUConfig Modbus RTU Configuration
* @brief Parameters for serial Modbus RTU communication.
* @{
*/
#include <ModbusRTU.h>
const int BAUDRATE = 19200; /**< @brief The serial communication speed in bits per second. */
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 1; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
ModbusRTU mb;
#endif
/**
* @brief The Modbus map for the Equipment device.
* This array defines all the Modbus points available on the emulated device.
* The `description` field is crucial as it's used to look up points within the application logic.
*/
modbusMap mb_map[] =
{
{HR, 33, 0, "V_LINE_AB_THD"},
{HR, 34, 0, "V_LINE_BC_THD"},
{HR, 35, 0, "V_LINE_CA_THD"},
{HR, 39, 0, "I_LINE_A_THD"},
{HR, 40, 0, "I_LINE_B_THD"},
{HR, 41, 0, "I_LINE_C_THD"},
{HR, 42, 0, "I_LINE_A_TDD"},
{HR, 43, 0, "I_LINE_B_TDD"},
{HR, 44, 0, "I_LINE_C_TDD"},
{HR, 53, 0, "V_LOAD_AB_THD"},
{HR, 54, 0, "V_LOAD_BC_THD"},
{HR, 55, 0, "V_LOAD_CA_THD"},
{HR, 59, 0, "I_LOAD_A_THD"},
{HR, 60, 0, "I_LOAD_B_THD"},
{HR, 61, 0, "I_LOAD_C_THD"},
{HR, 73, 0, "V_TUNE_AB_THD"},
{HR, 74, 0, "V_TUNE_BC_THD"},
{HR, 75, 0, "V_TUNE_CA_THD"},
{HR, 79, 0, "I_TUNE_A_THD"},
{HR, 80, 0, "I_TUNE_B_THD"},
{HR, 81, 0, "I_TUNE_C_THD"},
{HR, 100, 0, "P_LINE_APPARENT_TOTAL"},
{HR, 101, 0, "P_LINE_REAL_TOTAL"},
{HR, 102, 0, "P_LINE_REACTIVE_TOTAL"},
{HR, 103, 0, "P_LINE_POWER_FACTOR"},
{HR, 120, 0, "P_LOAD_APPARENT_TOTAL"},
{HR, 121, 0, "P_LOAD_REAL_TOTAL"},
{HR, 122, 0, "P_LOAD_REACTIVE_TOTAL"},
{HR, 123, 0, "P_LOAD_POWER_FACTOR"},
{HR, 124, 0, "P_LOAD_REAL_MEAS"},
{HR, 140, 0, "I_LINE_A_HARM_1"},
{HR, 141, 0, "I_LINE_A_HARM_3"},
{HR, 142, 0, "I_LINE_A_HARM_5"},
{HR, 143, 0, "I_LINE_A_HARM_7"},
{HR, 144, 0, "I_LINE_A_HARM_11"},
{HR, 145, 0, "I_LINE_A_HARM_13"},
{HR, 146, 0, "I_LINE_A_HARM_17"},
{HR, 147, 0, "I_LINE_A_HARM_19"},
{HR, 148, 0, "I_LINE_A_HARM_23"},
{HR, 149, 0, "I_LINE_A_HARM_25"},
{HR, 160, 0, "I_LINE_B_HARM_1"},
{HR, 161, 0, "I_LINE_B_HARM_3"},
{HR, 162, 0, "I_LINE_B_HARM_5"},
{HR, 163, 0, "I_LINE_B_HARM_7"},
{HR, 164, 0, "I_LINE_B_HARM_11"},
{HR, 165, 0, "I_LINE_B_HARM_13"},
{HR, 166, 0, "I_LINE_B_HARM_17"},
{HR, 167, 0, "I_LINE_B_HARM_19"},
{HR, 168, 0, "I_LINE_B_HARM_23"},
{HR, 169, 0, "I_LINE_B_HARM_25"},
{HR, 180, 0, "I_LINE_C_HARM_1"},
{HR, 181, 0, "I_LINE_C_HARM_3"},
{HR, 182, 0, "I_LINE_C_HARM_5"},
{HR, 183, 0, "I_LINE_C_HARM_7"},
{HR, 184, 0, "I_LINE_C_HARM_11"},
{HR, 185, 0, "I_LINE_C_HARM_13"},
{HR, 186, 0, "I_LINE_C_HARM_17"},
{HR, 187, 0, "I_LINE_C_HARM_19"},
{HR, 188, 0, "I_LINE_C_HARM_23"},
{HR, 189, 0, "I_LINE_C_HARM_25"},
{HR, 200, 0, "CNT_OPENED"},
{HR, 201, 0, "SYS_POWER_ON"},
{HR, 202, 0, "SYS_STATUS_OK"},
{HR, 203, 0, "SYS_AT_CAPACITY"},
{HR, 204, 0, "T_AMBIENT"},
{HR, 210, 0, "RECLOSE_LIMIT"},
{HR, 210, 0, "NCP_FAULT_A"},
{HR, 210, 0, "NCP_FAULT_B"},
{HR, 210, 0, "LINE_REACTOR_THERMAL_SW"},
{HR, 211, 0, "TUNE_PHASE_LOSS_A"},
{HR, 211, 0, "TUNE_PHASE_LOSS_B"},
{HR, 211, 0, "TUNE_PHASE_LOSS_C"},
{HR, 211, 0, "TUNE_ BALANCE_LOSS_A"},
{HR, 211, 0, "TUNE_ BALANCE_LOSS_B"},
{HR, 211, 0, "TUNE_ BALANCE_LOSS_C"},
{HR, 211, 0, "TUNE_UNDERCURRENT_A"},
{HR, 211, 0, "TUNE_UNDERCURRENT_B"},
{HR, 211, 0, "TUNE_UNDERCURRENT_C"},
{HR, 211, 0, "TUNE_OVERCURRENT_A"},
{HR, 211, 0, "TUNE_OVERCURRENT_B"},
{HR, 211, 0, "TUNE_OVERCURRENT_C"},
{HR, 211, 0, "UNDER_TEMP"},
{HR, 211, 0, "OVER_TEMP"},
{HR, 211, 0, "CPU_ERROR"},
{HR, 211, 0, "TUNE_REACTOR_THERMAL_SW"},
{HR, 212, 0, "PHASE_LOSS_A"},
{HR, 212, 0, "PHASE_LOSS_B"},
{HR, 212, 0, "PHASE_LOSS_C"},
{HR, 212, 0, "OVERVOLTAGE_A"},
{HR, 212, 0, "OVERVOLTAGE_B"},
{HR, 212, 0, "OVERVOLTAGE_C"},
{HR, 212, 0, "FILTER_FREQ_MISMATCH"},
{HR, 212, 0, "HIGH_VOLTAGE_THD"},
{HR, 212, 0, "LINE_PHASE_ROTATION"},
{HR, 250, 0, "SYS_CONTROL_MODE_RO"},
{HR, 251, 0, "TRACE_GO_DONE_RO"},
{HR, 256, 0, "SYS_STATE"},
{HR, 12, 0, ""},
};
//Size of modbus map used in FOR cycles, automatically calculated.
/**
* @brief The total number of entries in the `mb_map` array.
* This is calculated at compile time and used for iterating over the map.
*/
const int map_size = sizeof(mb_map) / sizeof(mb_map[0]);
/**
* @brief The main loop update interval in milliseconds.
*/
int interval = 250;
#endif // CONFIG_H

View File

@@ -0,0 +1,136 @@
/**
* @file State_Standby.cpp
* @brief Implementation of the StandbyState class.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-05
*
* This file contains the implementation for the StandbyState, which defines
* the behavior of the equipment when it is in an idle or standby mode.
*/
#include "States/State_Running.h"
#include "States/State_Fail.h"
#include "ModbusPoints/Modbus_Point.h"
#include "ModbusPoints/Modbus_FloatDecorator.h"
#include "Equipment/Equipment.h"
#include "Strategies/Strategy_Ramp.h"
#include "Strategies/Strategy_SingleValue.h"
#include <vector>
#include <string>
#if defined(USE_MODBUS_IP)
#include <ModbusIP_ESP8266.h>
#else
#include <ModbusRTU.h>
#endif
/**
* @brief Constructs a new StandbyState object.
*
* In this state, the equipment is idle. This constructor initializes several
* strategies to generate random values for various status points, simulating
* a live but non-operational unit.
*/
template<>
StandbyState<ModbusRTU>::StandbyState() {
addStrategy("V_LINE_AB_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_LINE_BC_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_LINE_CA_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_A_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_B_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_C_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_A_TDD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_B_TDD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_C_TDD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_LOAD_AB_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_LOAD_BC_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_LOAD_CA_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LOAD_AB_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LOAD_BC_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LOAD_CA_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_TUNE_AB_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_TUNE_BC_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("V_TUNE_CA_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_TUNE_A_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_TUNE_B_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_TUNE_C_THD", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("P_LINE_APPARENT_TOTAL", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("P_LINE_REAL_TOTAL", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("P_LINE_REACTIVE_TOTAL", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("P_LINE_POWER_FACTOR", new SingleValueStrategy(80.0f, 5.0f, 1000));
addStrategy("P_LOAD_APPARENT_TOTAL", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("P_LOAD_REAL_TOTAL", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("P_LOAD_REACTIVE_TOTAL", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("P_LOAD_POWER_FACTOR", new SingleValueStrategy(80.0f, 5.0f, 1000));
addStrategy("P_LOAD_REAL_MEAS", new SingleValueStrategy(5000.0f, 50.0f, 1000));
addStrategy("I_LINE_A_HARM_1", new SingleValueStrategy(55.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_3", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_5", new SingleValueStrategy(45.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_7", new SingleValueStrategy(40.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_11", new SingleValueStrategy(35.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_13", new SingleValueStrategy(30.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_17", new SingleValueStrategy(25.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_19", new SingleValueStrategy(20.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_23", new SingleValueStrategy(15.0f, 5.0f, 1000));
addStrategy("I_LINE_A_HARM_25", new SingleValueStrategy(10.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_1", new SingleValueStrategy(55.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_3", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_5", new SingleValueStrategy(45.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_7", new SingleValueStrategy(40.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_11", new SingleValueStrategy(35.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_13", new SingleValueStrategy(30.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_17", new SingleValueStrategy(25.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_19", new SingleValueStrategy(20.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_23", new SingleValueStrategy(15.0f, 5.0f, 1000));
addStrategy("I_LINE_B_HARM_25", new SingleValueStrategy(10.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_1", new SingleValueStrategy(55.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_3", new SingleValueStrategy(50.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_5", new SingleValueStrategy(45.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_7", new SingleValueStrategy(40.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_11", new SingleValueStrategy(35.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_13", new SingleValueStrategy(30.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_17", new SingleValueStrategy(25.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_19", new SingleValueStrategy(20.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_23", new SingleValueStrategy(15.0f, 5.0f, 1000));
addStrategy("I_LINE_C_HARM_25", new SingleValueStrategy(10.0f, 5.0f, 1000));
}
/**
* @brief Executes the standby state's logic for one update cycle.
*
* This method checks the "Chiller On-Off" Modbus point for a command to
* transition to the Running state. If no transition is requested, it applies
* the strategies defined for the standby state.
*
* @param equipment Pointer to the Equipment instance.
* @return A pointer to a new State if a transition should occur, otherwise nullptr.
*/
template<>
State<ModbusRTU>* StandbyState<ModbusRTU>::update(Equipment<ModbusRTU>* equipment) {
// STATE control, add conditions if change to a different state is needed
Serial.println("Standby update function");
// Apply any strategies defined for the standby state
_applyStrategies(equipment);
return nullptr;
}
/**
* @brief Logic to execute once when entering the standby state.
* Sets the "Chiller Sts" point to indicate the unit is not running.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void StandbyState<ModbusRTU>::enterState(Equipment<ModbusRTU>* equipment) {
// Logic to run when the equipment enters this state
Serial.println("Enter Standby State...");
}
/**
* @brief Logic to execute once when exiting the standby state.
* @param equipment Pointer to the Equipment instance.
*/
template<>
void StandbyState<ModbusRTU>::exitState(Equipment<ModbusRTU>* equipment) {
// Cleanup logic to run when the equipment leaves this state
}

View File

@@ -0,0 +1,142 @@
/**
* @file config.h
* @brief Main configuration file for the Daikin Chiller (RTU) emulator.
* @author Emmanuel Hernandez Cruz
* @date 2025-09-02
*
* This file contains important configurations for the Modbus RTU communication
* and the specific register map for the emulated device.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <ModbusRTU.h>
#include "core.h"
#include "Equipment/Equipment.h"
#if defined(USE_MODBUS_IP)
/**
* @defgroup ModbusTCPConfig Modbus IP Configuration
* @brief Parameters for Modbus TCP communication.
* @{
*/
#include <ModbusIP_ESP8266.h>
const char *ssid = "wifi_name"; /**< @brief The SSID of the WiFi network. */
const char *password = "wifi_password"; /**< @brief The password for the WiFi network. */
IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */
IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */
IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */
ModbusIP mb;
#else
/**
* @defgroup ModbusRTUConfig Modbus RTU Configuration
* @brief Parameters for serial Modbus RTU communication.
* @{
*/
#include <ModbusRTU.h>
const int BAUDRATE = 19200; /**< @brief The serial communication speed in bits per second. */
const int RX_PIN = 17; /**< @brief The GPIO pin used for receiving data (RX). */
const int TX_PIN = 16; /**< @brief The GPIO pin used for transmitting data (TX). */
const int RST_PIN = 4; /**< @brief The GPIO pin connected to the RS485 driver's DE/RE pins for direction control. */
const int MODBUS_ID = 6; /**< @brief The unique slave ID for this device on the Modbus bus. */
/** @} */
/** @brief Global instance of the Modbus RTU server. */
ModbusRTU mb;
#endif
/**
* @brief The Modbus map for the Equipment device.
* This array defines all the Modbus points available on the emulated device.
* The `description` field is crucial as it's used to look up points within the application logic.
*/
modbusMap mb_map[] =
{
{HR, 32, 0, "V_LINE_AB_THD"},
{HR, 33, 0, "V_LINE_BC_THD"},
{HR, 34, 0, "V_LINE_CA_THD"},
{HR, 38, 0, "I_LINE_A_THD"},
{HR, 39, 0, "I_LINE_B_THD"},
{HR, 40, 0, "I_LINE_C_THD"},
{HR, 41, 0, "I_LINE_A_TDD"},
{HR, 42, 0, "I_LINE_B_TDD"},
{HR, 43, 0, "I_LINE_C_TDD"},
{HR, 52, 0, "V_LOAD_AB_THD"},
{HR, 53, 0, "V_LOAD_BC_THD"},
{HR, 54, 0, "V_LOAD_CA_THD"},
{HR, 58, 0, "I_LOAD_A_THD"},
{HR, 59, 0, "I_LOAD_B_THD"},
{HR, 60, 0, "I_LOAD_C_THD"},
{HR, 72, 0, "V_TUNE_AB_THD"},
{HR, 73, 0, "V_TUNE_BC_THD"},
{HR, 74, 0, "V_TUNE_CA_THD"},
{HR, 78, 0, "I_TUNE_A_THD"},
{HR, 79, 0, "I_TUNE_B_THD"},
{HR, 80, 0, "I_TUNE_C_THD"},
{HR, 99, 0, "P_LINE_APPARENT_TOTAL"},
{HR, 100, 0, "P_LINE_REAL_TOTAL"},
{HR, 102, 0, "P_LINE_REACTIVE_TOTAL"},
{HR, 103, 0, "P_LINE_POWER_FACTOR"},
{HR, 119, 0, "P_LOAD_APPARENT_TOTAL"},
{HR, 120, 0, "P_LOAD_REAL_TOTAL"},
{HR, 121, 0, "P_LOAD_REACTIVE_TOTAL"},
{HR, 122, 0, "P_LOAD_POWER_FACTOR"},
{HR, 123, 0, "P_LOAD_REAL_MEAS"},
{HR, 139, 0, "I_LINE_A_HARM_1"},
{HR, 140, 0, "I_LINE_A_HARM_3"},
{HR, 141, 0, "I_LINE_A_HARM_5"},
{HR, 142, 0, "I_LINE_A_HARM_7"},
{HR, 143, 0, "I_LINE_A_HARM_11"},
{HR, 144, 0, "I_LINE_A_HARM_13"},
{HR, 145, 0, "I_LINE_A_HARM_17"},
{HR, 146, 0, "I_LINE_A_HARM_19"},
{HR, 147, 0, "I_LINE_A_HARM_23"},
{HR, 148, 0, "I_LINE_A_HARM_25"},
{HR, 159, 0, "I_LINE_B_HARM_1"},
{HR, 160, 0, "I_LINE_B_HARM_3"},
{HR, 161, 0, "I_LINE_B_HARM_5"},
{HR, 162, 0, "I_LINE_B_HARM_7"},
{HR, 163, 0, "I_LINE_B_HARM_11"},
{HR, 164, 0, "I_LINE_B_HARM_13"},
{HR, 165, 0, "I_LINE_B_HARM_17"},
{HR, 166, 0, "I_LINE_B_HARM_19"},
{HR, 167, 0, "I_LINE_B_HARM_23"},
{HR, 168, 0, "I_LINE_B_HARM_25"},
{HR, 179, 0, "I_LINE_C_HARM_1"},
{HR, 180, 0, "I_LINE_C_HARM_3"},
{HR, 181, 0, "I_LINE_C_HARM_5"},
{HR, 182, 0, "I_LINE_C_HARM_7"},
{HR, 183, 0, "I_LINE_C_HARM_11"},
{HR, 184, 0, "I_LINE_C_HARM_13"},
{HR, 185, 0, "I_LINE_C_HARM_17"},
{HR, 186, 0, "I_LINE_C_HARM_19"},
{HR, 187, 0, "I_LINE_C_HARM_23"},
{HR, 188, 0, "I_LINE_C_HARM_25"},
{HR, 199, 0, "CNT_OPENED"},
{HR, 200, 0, "SYS_POWER_ON"},
{HR, 201, 0, "SYS_STATUS_OK"},
{HR, 202, 0, "SYS_AT_CAPACITY"},
{HR, 203, 0, "T_AMBIENT"},
{HR, 209, 0, "Alm_group_1"},
{HR, 210, 0, "Alm_group_2"},
{HR, 211, 0, "Alm_group_3"},
{HR, 249, 0, "SYS_CONTROL_MODE"},
{HR, 250, 0, "TRACE_GO_DONE"},
{HR, 255, 0, "SYS_STATE"},
};
//Size of modbus map used in FOR cycles, automatically calculated.
/**
* @brief The total number of entries in the `mb_map` array.
* This is calculated at compile time and used for iterating over the map.
*/
const int map_size = sizeof(mb_map) / sizeof(mb_map[0]);
/**
* @brief The main loop update interval in milliseconds.
*/
int interval = 250;
#endif // CONFIG_H