diff --git a/platformio.ini b/platformio.ini index f577bb4..75883ff 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = BKR_ABB_XT_TCP ; Select here the name of the configuration you want to download +default_envs = BKR_Eaton_PXR20_25 ; Select here the name of the configuration you want to download [env] upload_port = COM50 @@ -149,4 +149,18 @@ platform = espressif32 board = dfrobot_firebeetle2_esp32e extends = common_env_options build_flags = -D USE_MODBUS_IP -build_src_filter = -<*> + \ No newline at end of file +build_src_filter = -<*> + + +[env:BKR_Susol_ACB_TCP] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = -D USE_MODBUS_IP +build_src_filter = -<*> + + +[env:BKR_Eaton_PXR20_25] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = -D USE_MODBUS_IP +build_src_filter = -<*> + \ No newline at end of file diff --git a/src/EPMS/Breaker/Eaton_PXR20_25/README.md b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/README.md similarity index 100% rename from src/EPMS/Breaker/Eaton_PXR20_25/README.md rename to src/EPMS/Breaker/BKR_Eaton_PXR20_25/README.md diff --git a/src/EPMS/Breaker/Eaton_PXR20_25/State_Fail.cpp b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Fail.cpp similarity index 100% rename from src/EPMS/Breaker/Eaton_PXR20_25/State_Fail.cpp rename to src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Fail.cpp diff --git a/src/EPMS/Breaker/MOD_600/State_Running.cpp b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp similarity index 59% rename from src/EPMS/Breaker/MOD_600/State_Running.cpp rename to src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp index b9e4a99..16d2903 100644 --- a/src/EPMS/Breaker/MOD_600/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp @@ -38,6 +38,16 @@ */ template<> RunningState::RunningState() { + addStrategy("Volts AB", new SingleValueStrategy(480.0F, 5.0f, 1000)); + addStrategy("Volts BC", new SingleValueStrategy(480.0F, 5.0f, 1000)); + addStrategy("Volts CA", new SingleValueStrategy(480.0F, 5.0f, 1000)); + + addStrategy("PF", new SingleValueStrategy(0.9f, 0.05f, 1000)); + + addStrategy("Amps A", new SingleValueStrategy(1.0f, 10.0f, 1000)); + addStrategy("Amps B", new SingleValueStrategy(1.0f, 10.0f, 1000)); + addStrategy("Amps C", new SingleValueStrategy(1.0f, 10.0f, 1000)); + } /** @@ -57,7 +67,41 @@ template<> State* RunningState::update(Equipment* equipment) { // STATE control, add conditions if change to a different state is needed Serial.println("Running update function"); - + float State_Ctrl = getPointValue(equipment, "State Control"); + if (State_Ctrl == 1){ + return new StandbyState(); + } + // Apply any strategies defined for the standby state + float volts_AB = getPointValue(equipment, "Volts AB"); + float volts_BC = getPointValue(equipment, "Volts BC"); + float volts_AC = getPointValue(equipment, "Volts CA"); + + setPointValue(equipment, "Volts AN", volts_AB/1.732); + setPointValue(equipment, "Volts BN", volts_BC/1.732); + setPointValue(equipment, "Volts CN", volts_AC/1.732); + + + int I_load = getPointValue(equipment, "Load"); + int I_rating = getPointValue(equipment, "Rating"); + float load = static_cast(I_load); + float rating = static_cast(I_rating); + float real_load = rating * (load/100.0f); + Strategy_Behavior* ampsA_svs = getStrategy("Amps A"); + Strategy_Behavior* ampsB_svs = getStrategy("Amps B"); + Strategy_Behavior* ampsC_svs = getStrategy("Amps C"); + + static_cast(ampsA_svs)->setSetpoint(real_load); + static_cast(ampsB_svs)->setSetpoint(real_load); + static_cast(ampsC_svs)->setSetpoint(real_load); + + float pf = getPointValue(equipment, "PF"); + + + float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/3.0f) * real_load * pf)/1000; + float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/3.0f) * real_load)/1000; + + setPointValue(equipment, "kW", kw); + setPointValue(equipment, "kVA", kva); // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -73,6 +117,7 @@ void RunningState::enterState(Equipment* 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 + setPointValue(equipment, "CB Position", 2048); } diff --git a/src/EPMS/Breaker/Eaton_PXR20_25/State_Standby.cpp b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp similarity index 81% rename from src/EPMS/Breaker/Eaton_PXR20_25/State_Standby.cpp rename to src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp index 20029d1..5dd2e42 100644 --- a/src/EPMS/Breaker/Eaton_PXR20_25/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp @@ -56,7 +56,10 @@ template<> State* StandbyState::update(Equipment* equipment) { // STATE control, add conditions if change to a different state is needed Serial.println("Standby update function"); - + float State_Ctrl = getPointValue(equipment, "State Control"); + if (State_Ctrl == 2){ + return new RunningState(); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -72,6 +75,17 @@ template<> void StandbyState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Standby State..."); + setPointValue(equipment, "CB Position", 0); + setPointValue(equipment, "Volts AB", 0.0f); + setPointValue(equipment, "Volts BC", 0.0f); + setPointValue(equipment, "Volts CA", 0.0f); + setPointValue(equipment, "Volts AN", 0.0f); + setPointValue(equipment, "Volts BN", 0.0f); + setPointValue(equipment, "Volts CN", 0.0f); + setPointValue(equipment, "PF", 0.0f); + setPointValue(equipment, "Amps A", 0.0f); + setPointValue(equipment, "Amps B", 0.0f); + setPointValue(equipment, "Amps C", 0.0f); } /** @@ -82,4 +96,5 @@ template<> void StandbyState::exitState(Equipment* equipment) { // Cleanup logic to run when the equipment leaves this state Serial.println("Exit Standby State..."); + } \ No newline at end of file diff --git a/src/EPMS/Breaker/MOD_600/config.h b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h similarity index 73% rename from src/EPMS/Breaker/MOD_600/config.h rename to src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h index 38c73dd..79be276 100644 --- a/src/EPMS/Breaker/MOD_600/config.h +++ b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h @@ -60,25 +60,26 @@ */ modbusMap mb_map[] = { - {HR, 15, 0, "State Control"}, //Internal to control from Modscan - {HR, 16, 0, "Fault Code"}, //Internal Fault code from Modscan - {IR_FLOAT, 214, 0, "Amps A"}, - {IR_FLOAT, 216, 0, "Amps B"}, - {IR_FLOAT, 218, 0, "AMPS C"}, - {IR_FLOAT, 220, 0, "Amps N"}, - {IR_FLOAT, 222, 0, "Amps G"}, - {IR, 206, 0, "Status word"}, //Bit 12 Position, Bit 9 Trip - {IR_FLOAT, 254, 0, "Total Apparent Power (kVA)"}, - {IR_FLOAT, 250, 0, "Total Effective Power (kW)"}, - {IR_FLOAT, 264, 0, "kWh_Reg1"}, - {IR_FLOAT, 266, 0, "kWh_Reg2"}, - {IR_FLOAT, 248, 0, "Power Factor"}, - {IR_FLOAT, 236, 0, "Volts A-B"}, - {IR_FLOAT, 230, 0, "Volts A-N"}, - {IR_FLOAT, 238, 0, "Volts B-C"}, - {IR_FLOAT, 232, 0, "Volts B-N"}, - {IR_FLOAT, 240, 0, "Volts C-A"}, - {IR_FLOAT, 234, 0, "Volts C-N"}, + {HR, 9, 0, "State Control"}, //Open-Close Cmd + {HR, 10, 0, "Load"}, //Adjustble Load + {HR, 11, 0, "Rating"}, //Max amp to calculate kw, kVA, etc + {HR_FLOAT, 4610, 0, "Amps A"}, + {HR_FLOAT, 4612, 0, "Amps B"}, + {HR_FLOAT, 4614, 0, "Amps C"}, + {HR_FLOAT, 4616, 0, "Amps G"}, + {HR_FLOAT, 4618, 0, "Amps N"}, + {HR_FLOAT, 4622, 0, "Volts AB"}, + {HR_FLOAT, 4624, 0, "Volts BC"}, + {HR_FLOAT, 4626, 0, "Volts CA"}, + {HR_FLOAT, 4630, 0, "Volts AN"}, + {HR_FLOAT, 4632, 0, "Volts BN"}, + {HR_FLOAT, 4634, 0, "Volts CN"}, + {HR_FLOAT, 4650, 0, "kW"}, + {HR_FLOAT, 4654, 0, "kVA"}, + {HR_FLOAT, 4658, 0, "PF"}, + {HR_FLOAT, 6262, 0, "kWh"}, + {DI, 1000, 0, "CB Position"}, + {DI, 1001, 0, "CB Trip"}, }; //Size of modbus map used in FOR cycles, automatically calculated. diff --git a/src/EPMS/Breaker/Eaton_PXR20_25/main.cpp b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/main.cpp similarity index 100% rename from src/EPMS/Breaker/Eaton_PXR20_25/main.cpp rename to src/EPMS/Breaker/BKR_Eaton_PXR20_25/main.cpp diff --git a/src/EPMS/Breaker/MOD_225/README.md b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/README.md similarity index 100% rename from src/EPMS/Breaker/MOD_225/README.md rename to src/EPMS/Breaker/BKR_Susol_ACB_TCP/README.md diff --git a/src/EPMS/Breaker/MOD_600/State_Fail.cpp b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Fail.cpp similarity index 95% rename from src/EPMS/Breaker/MOD_600/State_Fail.cpp rename to src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Fail.cpp index 8bc0385..17f120b 100644 --- a/src/EPMS/Breaker/MOD_600/State_Fail.cpp +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Fail.cpp @@ -53,6 +53,10 @@ template<> State* FailState::update(Equipment* equipment) { // STATE control, add conditions if change to a different state is needed Serial.println("Fail update function"); + float State_Ctrl = getPointValue(equipment, "State Control"); + if (State_Ctrl == 1){ + return new StandbyState(); + } _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/Breaker/Eaton_PXR20_25/State_Running.cpp b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp similarity index 74% rename from src/EPMS/Breaker/Eaton_PXR20_25/State_Running.cpp rename to src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp index b9e4a99..3fb5e0b 100644 --- a/src/EPMS/Breaker/Eaton_PXR20_25/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp @@ -32,12 +32,15 @@ /** * @brief Constructs a new RunningState object. * - * This constructor initializes behavior strategies active during the running + * This constructor initializes behavior strategies active during the runnings * state, such as a PID controller for the 'CW Valve Position' and totalizers * for the run-hours of each EC fan. */ template<> RunningState::RunningState() { + addStrategy("Amps A", new SingleValueStrategy(1.0f, 5.0f, 1000)); + addStrategy("Amps B", new SingleValueStrategy(1.0f, 5.0f, 1000)); + addStrategy("Amps C", new SingleValueStrategy(1.0f, 5.0f, 1000)); } /** @@ -57,8 +60,24 @@ template<> State* RunningState::update(Equipment* equipment) { // STATE control, add conditions if change to a different state is needed Serial.println("Running update function"); - + float State_Ctrl = getPointValue(equipment, "State Control"); + if (State_Ctrl == 1){ + return new StandbyState(); + } + // Apply any strategies defined for the standby state + int I_load = getPointValue(equipment, "Load"); + int I_rating = getPointValue(equipment, "Rating"); + float load = static_cast(I_load); + float rating = static_cast(I_rating); + float real_load = rating * (load/100.0f); + Strategy_Behavior* ampsA_svs = getStrategy("Amps A"); + Strategy_Behavior* ampsB_svs = getStrategy("Amps B"); + Strategy_Behavior* ampsC_svs = getStrategy("Amps C"); + + static_cast(ampsA_svs)->setSetpoint(real_load); + static_cast(ampsB_svs)->setSetpoint(real_load); + static_cast(ampsC_svs)->setSetpoint(real_load); _applyStrategies(equipment); return nullptr; } @@ -73,6 +92,7 @@ void RunningState::enterState(Equipment* 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 + setPointValue(equipment, "Status", 4); } diff --git a/src/EPMS/Breaker/MOD_600/State_Standby.cpp b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp similarity index 88% rename from src/EPMS/Breaker/MOD_600/State_Standby.cpp rename to src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp index 20029d1..c7a1db4 100644 --- a/src/EPMS/Breaker/MOD_600/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp @@ -37,8 +37,8 @@ */ template<> StandbyState::StandbyState() { - // You can add initialization code here if needed - + // You can add initialization code here if needed + } @@ -56,7 +56,10 @@ template<> State* StandbyState::update(Equipment* equipment) { // STATE control, add conditions if change to a different state is needed Serial.println("Standby update function"); - + float State_Ctrl = getPointValue(equipment, "State Control"); + if (State_Ctrl == 2){ + return new RunningState(); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -72,6 +75,11 @@ template<> void StandbyState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Standby State..."); + setPointValue(equipment, "Status", 0); + + setPointValue(equipment, "Amps A", 0.0f); + setPointValue(equipment, "Amps B", 0.0f); + setPointValue(equipment, "Amps C", 0.0f); } /** diff --git a/src/EPMS/Breaker/MOD_225/config.h b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h similarity index 77% rename from src/EPMS/Breaker/MOD_225/config.h rename to src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h index 0337fee..2ee81ea 100644 --- a/src/EPMS/Breaker/MOD_225/config.h +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h @@ -23,8 +23,8 @@ #include 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 local_IP(192, 168, 1, 238); /**< @brief The static IP address for the device. */ + IPAddress gateway(192, 138, 1, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -60,14 +60,17 @@ */ modbusMap mb_map[] = { - {HR, 15, 0, "State Control"}, //Internal to control from Modscan - {HR, 16, 0, "Fault Code"}, //Internal Fault code from Modscan - {HR, 30003, 0, "Amps A"}, //These look to be 8 bit registers and we need to poll the 16 bit word - {HR, 30005, 0, "Amps B"}, - {HR, 30007, 0, "AMPS C"}, - {HR, 12001, 0, "CB Position"}, //This is in the ignition UDT and looking at bit 0 - {HR, 30013, 0, "IDMTL Format OCR inform. 2"}, //Trip status at bit 0 -}; + {HR, 9, 0, "State Control"}, + {HR, 10, 0, "Load"}, + {HR, 11, 0, "Rating"}, + + {IR, 2, 0, "Status"}, + {IR, 3, 0, "Amps A"}, + {IR, 5, 0, "Amps B"}, + {IR, 7, 0, "Amps C"}, + {IR, 9, 0, "Amps N"}, + +}; //Size of modbus map used in FOR cycles, automatically calculated. /** diff --git a/src/EPMS/Breaker/MOD_225/main.cpp b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/main.cpp similarity index 100% rename from src/EPMS/Breaker/MOD_225/main.cpp rename to src/EPMS/Breaker/BKR_Susol_ACB_TCP/main.cpp diff --git a/src/EPMS/Breaker/Eaton_PXR20_25/config.h b/src/EPMS/Breaker/Eaton_PXR20_25/config.h deleted file mode 100644 index eeb4173..0000000 --- a/src/EPMS/Breaker/Eaton_PXR20_25/config.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @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 - 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 - 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[] = -{ - {HR, 15, 0, "State Control"}, //Internal to control from Modscan - {HR, 16, 0, "Fault Code"}, //Internal Fault code from Modscan - {HR_FLOAT, 4611, 0, "Amps A"}, - {HR_FLOAT, 4613, 0, "Amps B"}, - {HR_FLOAT, 4615, 0, "AMPS C"}, - {HR_FLOAT, 4617, 0, "Amps G"}, - {HR_FLOAT, 4619, 0, "Amps N"}, - {HR_FLOAT, 4655, 0, "kVA"}, - {HR_FLOAT, 4651, 0, "kW"}, - {HR_FLOAT, 6263, 0, "kWh"}, - {HR_FLOAT, 4659, 0, "Power Factor (PF)"}, - {HR_FLOAT, 4623, 0, "Volts AB"}, - {HR_FLOAT, 4621, 0, "Volts AN"}, - {HR_FLOAT, 4625, 0, "Volts BC"}, - {HR_FLOAT, 4633, 0, "Volts BN"}, - {HR_FLOAT, 4627, 0, "Volts CA"}, - {HR_FLOAT, 4635, 0, "Volts CN"}, - {DI, 1001, 0, "Breaker is in the Closed Position"}, - {DI, 1002, 0, "Unacknowledged Trip Condition"}, -}; -//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 diff --git a/src/EPMS/Breaker/MOD_225/State_Fail.cpp b/src/EPMS/Breaker/MOD_225/State_Fail.cpp deleted file mode 100644 index 8bc0385..0000000 --- a/src/EPMS/Breaker/MOD_225/State_Fail.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @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 -#else - #include -#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::FailState(const std::vector& 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* FailState::update(Equipment* 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::enterState(Equipment* 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::exitState(Equipment* equipment) { - // Cleanup logic to run when the equipment leaves this state - Serial.println("Exit Fail State..."); -} \ No newline at end of file diff --git a/src/EPMS/Breaker/MOD_225/State_Running.cpp b/src/EPMS/Breaker/MOD_225/State_Running.cpp deleted file mode 100644 index b9e4a99..0000000 --- a/src/EPMS/Breaker/MOD_225/State_Running.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @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 -#include -#if defined(USE_MODBUS_IP) - #include -#else - #include -#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::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* RunningState::update(Equipment* 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::enterState(Equipment* 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::exitState(Equipment* equipment) { - // Cleanup logic to run when the equipment leaves this state - Serial.println("Exit Running State..."); - -} \ No newline at end of file diff --git a/src/EPMS/Breaker/MOD_225/State_Standby.cpp b/src/EPMS/Breaker/MOD_225/State_Standby.cpp deleted file mode 100644 index 20029d1..0000000 --- a/src/EPMS/Breaker/MOD_225/State_Standby.cpp +++ /dev/null @@ -1,85 +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 "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 -#include -#if defined(USE_MODBUS_IP) - #include -#else - #include -#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::StandbyState() { - // You can add initialization code here if needed - - -} - -/** - * @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* StandbyState::update(Equipment* 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::enterState(Equipment* 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::exitState(Equipment* equipment) { - // Cleanup logic to run when the equipment leaves this state - Serial.println("Exit Standby State..."); -} \ No newline at end of file diff --git a/src/EPMS/Breaker/MOD_600/README.md b/src/EPMS/Breaker/MOD_600/README.md deleted file mode 100644 index 4f156e3..0000000 --- a/src/EPMS/Breaker/MOD_600/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Daikin Chiller (RTU) Emulator - -This project is an Arduino-based emulator for a Daikin Chiller unit, communicating over Modbus RTU. It is designed to be a flexible template that can be adapted to simulate different types of chillers by modifying the configuration and state logic. - -The emulator operates on a state machine with three core states: -* **Standby**: The chiller is idle but ready. -* **Running**: The chiller is active and operational. -* **Fail**: The chiller has encountered a fault condition. - -## Features - -* **Modbus RTU Communication**: Emulates a Modbus slave device. -* **State Machine Logic**: Simulates different operational states (Standby, Running, Fail). -* **Dynamic Value Simulation**: Uses "Strategies" (e.g., PID, Ramp) to generate realistic, changing values for Modbus points. -* **Configurable Modbus Map**: The entire Modbus register map is defined in a single, easy-to-modify file (`config.h`). -* **Extensible Design**: The structure allows for the addition of new states and behaviors. - -## Hardware Prerequisites - -The code is written for an ESP8266/ESP32-style microcontroller with WiFi capabilities and at least one hardware serial port for RS485 communication. - -* **Microcontroller**: ESP8266, ESP32, or similar. -* **RS485 Transceiver**: A module like the MAX485 to interface with the Modbus RTU bus. - -## Software Dependencies - -This project relies on a Modbus library. Ensure you have the correct library installed in your Arduino IDE. - -* **Modbus Library**: The code uses a library that provides `ModbusRTU.h` and optionally `ModbusIP_ESP8266.h`. - ---- - -## How to Customize for a New Chiller - -To adapt this template for a new chiller, follow these steps. - -### 1. Configure Device-Specific Parameters (`config.h`) - -Open `CH_Daikin_AWV026B_RTU/config.h`. This is the main file for device-specific settings. - -#### Modbus RTU Settings -Update the following constants for your device's serial communication setup. -```c++ -const int BAUDRATE = 19200; // The serial communication speed -const int RX_PIN = 17; // The GPIO pin for receiving data (RX) -const int TX_PIN = 16; // The GPIO pin for transmitting data (TX) -const int RST_PIN = 4; // The GPIO pin for RS485 direction control -const int MODBUS_ID = 1; // The unique slave ID for this device \ No newline at end of file diff --git a/src/EPMS/Breaker/MOD_600/main.cpp b/src/EPMS/Breaker/MOD_600/main.cpp deleted file mode 100644 index 286a98c..0000000 --- a/src/EPMS/Breaker/MOD_600/main.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @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 -#include "config.h" -#include "ModbusPoints/Modbus_PointFactory.h" -#if defined(USE_MODBUS_IP) - #include -#else - #include -#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* 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); - } -}