From a24462e77b155dcc0a6e775e53767b8b1a07cc46 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Fri, 24 Oct 2025 13:24:59 -0500 Subject: [PATCH 01/51] save --- .../PDU_Maverick_Power_TCP/State_Running.cpp | 10 ++- src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h | 2 +- .../UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp | 65 +++++++++------ .../UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp | 79 ++++++++++--------- .../UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp | 70 ++++++++-------- .../UPS/UPS_Vertiv_APM2_TCP/State_Standby.cpp | 57 ++++++++++++- src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h | 7 +- 7 files changed, 185 insertions(+), 105 deletions(-) diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp index 153ba0f..df33296 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp @@ -161,6 +161,8 @@ State* RunningState::update(Equipment* equipment) if (cb_status == 1.0f){ setBitValue(equipment, "CB_Status", cb_num, true); + setBitValue(equipment, "CB_Tripped", cb_num, false); + strategy = getStrategy("Amps G"); static_cast(strategy)->setSetpoint(65.0f); strategy = getStrategy("Amps N"); @@ -224,7 +226,13 @@ State* RunningState::update(Equipment* equipment) setPointValue(equipment, tag, total_load * 1715.0f * 0.9f); - }else{ + } + else{ + if (cb_status == 2.0f){ + setBitValue(equipment, "CB_Tripped", cb_num, true); + } else { + setBitValue(equipment, "CB_Tripped", cb_num, false); + } setBitValue(equipment, "CB_Status", cb_num, false); strategy = getStrategy("Amps G"); static_cast(strategy)->setSetpoint(0.0f); diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h index db59a4b..3bb5f0c 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 178); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 33, 181); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp index 29c1e91..ce7c1a1 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp @@ -60,11 +60,12 @@ BatteryState::BatteryState() { addStrategy("System Output Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); addStrategy("System Output Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); addStrategy("System Output Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs A", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs B", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs C", new RampStrategy(10.0F, 5.0f, 1000)); addStrategy("Battery Time Remaining", new RampStrategy(0.0F, 0.3f, 1000)); + addStrategy("Percentage Load", new RampStrategy(0.0F, 1.0f, 1000)); } /** @@ -120,7 +121,7 @@ State* BatteryState::update(Equipment* equipment) float Out_PFa = getPointValue(equipment, "System Output Power Factor Phs A"); ramp_strat = getStrategy("System Output Power Phase A"); static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia); - ramp_strat = getStrategy("System Output Apparent Power Phase A"); + ramp_strat = getStrategy("System Output Apparent Power Phs A"); static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * Out_PFa); float Out_Vbn = getPointValue(equipment, "System Output RMS B-N"); @@ -128,7 +129,7 @@ State* BatteryState::update(Equipment* equipment) float Out_PFb = getPointValue(equipment, "System Output Power Factor Phs B"); ramp_strat = getStrategy("System Output Power Phase B"); static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib); - ramp_strat = getStrategy("System Output Apparent Power Phase B"); + ramp_strat = getStrategy("System Output Apparent Power Phs B"); static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * Out_PFb); float Out_Vcn = getPointValue(equipment, "System Output RMS C-N"); @@ -136,7 +137,7 @@ State* BatteryState::update(Equipment* equipment) float Out_PFc = getPointValue(equipment, "System Output Power Factor Phs C"); ramp_strat = getStrategy("System Output Power Phase C"); static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic); - ramp_strat = getStrategy("System Output Apparent Power Phase C"); + ramp_strat = getStrategy("System Output Apparent Power Phs C"); static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * Out_PFc); float Battery_time = getPointValue(equipment, "Battery Time Remaining"); @@ -167,23 +168,43 @@ State* BatteryState::update(Equipment* equipment) */ template<> void BatteryState::enterState(Equipment* equipment) { - // Logic to run when the equipment enters this state - Serial.println("Enter Battery State..."); + // Logic to run when the equipment enters this state + Serial.println("Enter Battery State..."); + setPointValue(equipment, "System Input RMS A-B", 0.0f); + setPointValue(equipment, "System Input RMS B-C", 0.0f); + setPointValue(equipment, "System Input RMS C-A", 0.0f); + setPointValue(equipment, "System Input RMS A-N", 0.0f); + setPointValue(equipment, "System Input RMS B-N", 0.0f); + setPointValue(equipment, "System Input RMS C-N", 0.0f); + setPointValue(equipment, "System Input RMS Current Phase A", 0.0f); + setPointValue(equipment, "System Input RMS Current Phase B", 0.0f); + setPointValue(equipment, "System Input RMS Current Phase C", 0.0f); + setPointValue(equipment, "System Input Frequency", 0.0f); + setPointValue(equipment, "System Input Power Factor Phs A", 0.0f); + setPointValue(equipment, "System Input Power Factor Phs B", 0.0f); + setPointValue(equipment, "System Input Power Factor Phs C", 0.0f); + setPointValue(equipment, "System Input Power Phase A", 0.0f); + setPointValue(equipment, "System Input Power Phase B", 0.0f); + setPointValue(equipment, "System Input Power Phase C", 0.0f); + setPointValue(equipment, "System Input Apparent Power Phs A", 0.0f); + setPointValue(equipment, "System Input Apparent Power Phs B", 0.0f); + setPointValue(equipment, "System Input Apparent Power Phs C", 0.0f); - setPointValue(equipment, "Bypass Input Voltage RMS A-B", 0.0f); - setPointValue(equipment, "Bypass Input Voltage RMS B-C", 0.0f); - setPointValue(equipment, "Bypass Input Voltage RMS C-A", 0.0f); - setPointValue(equipment, "Bypass Input Voltage RMS A-N", 0.0f); - setPointValue(equipment, "Bypass Input Voltage RMS B-N", 0.0f); - setPointValue(equipment, "Bypass Input Voltage RMS C-N", 0.0f); - setPointValue(equipment, "Bypass Input Frequency", 0.0f); - setPointValue(equipment, "Bypass Power Phase A", 0.0f); - setPointValue(equipment, "Bypass Power Phase B", 0.0f); - setPointValue(equipment, "Bypass Power Phase C", 0.0f); - - setPointValue(equipment, "UPS Loading Status", 6.0f); - setPointValue(equipment, "UPS Battery Status2", 2.0f); - // You could also update a Modbus register to show the "standby" state + + setPointValue(equipment, "Bypass Input Voltage RMS A-B", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS B-C", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS C-A", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS A-N", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS B-N", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS C-N", 0.0f); + setPointValue(equipment, "Bypass Input Frequency", 0.0f); + setPointValue(equipment, "Bypass Power Phase A", 0.0f); + setPointValue(equipment, "Bypass Power Phase B", 0.0f); + setPointValue(equipment, "Bypass Power Phase C", 0.0f); + setPointValue(equipment, "UPS Loading Status", 6.0f); + setPointValue(equipment, "UPS Battery Status2", 2.0f); + + // You could also update a Modbus register to show the "standby" state } diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp index 9a1012d..73a2b31 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp @@ -49,9 +49,9 @@ BypassState::BypassState() { addStrategy("System Input RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); addStrategy("System Input RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Input RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Input RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Input RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); addStrategy("System Input Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); @@ -59,12 +59,12 @@ BypassState::BypassState() { addStrategy("System Input Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); addStrategy("System Input Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase A", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase B", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase C", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Apparent Power Phs A", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Apparent Power Phs B", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Apparent Power Phs C", new RampStrategy(0.0F, 5.0f, 1000)); //Bypass System @@ -77,9 +77,9 @@ BypassState::BypassState() { addStrategy("Bypass Input Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); - addStrategy("Bypass Input Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("Bypass Input Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("Bypass Input Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("Bypass Input Power Phase A", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("Bypass Input Power Phase B", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("Bypass Input Power Phase C", new RampStrategy(0.0F, 1.0f, 1000)); //Output System addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); @@ -89,9 +89,9 @@ BypassState::BypassState() { addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Output RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Output RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); addStrategy("System Output Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); @@ -99,12 +99,12 @@ BypassState::BypassState() { addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Power Phase A", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Output Power Phase B", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Output Power Phase C", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs A", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs B", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs C", new RampStrategy(0.0F, 5.0f, 1000)); addStrategy("Battery Time Remaining", new RampStrategy(480.0F, 0.3f, 1000)); addStrategy("DC Bus Voltage", new SingleValueStrategy(518.0F, 5.0f, 1000)); @@ -163,30 +163,30 @@ State* BypassState::update(Equipment* equipment) { float In_PFa = getPointValue(equipment, "System Input Power Factor Phs A"); ramp_strat = getStrategy("System Input Power Phase A"); static_cast(ramp_strat)->setTarget(In_Van * In_Ia); - ramp_strat = getStrategy("Bypass Power Phase A"); + ramp_strat = getStrategy("Bypass Input Power Phase A"); static_cast(ramp_strat)->setTarget(In_Van * In_Ia); - ramp_strat = getStrategy("System Input Apparent Power Phase A"); - static_cast(ramp_strat)->setTarget(In_Van * In_Ia * In_PFa); - + ramp_strat = getStrategy("System Input Apparent Power Phs A"); + static_cast(ramp_strat)->setTarget(In_Van * In_Ia * 0.9f); + float In_Vbn = getPointValue(equipment, "System Input RMS B-N"); float In_Ib = getPointValue(equipment, "System Input RMS Current Phase B"); float In_PFb = getPointValue(equipment, "System Input Power Factor Phs B"); ramp_strat = getStrategy("System Input Power Phase B"); static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib); - ramp_strat = getStrategy("Bypass Power Phase B"); + ramp_strat = getStrategy("Bypass Input Power Phase B"); static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib); - ramp_strat = getStrategy("System Input Apparent Power Phase B"); - static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib * In_PFb); - + ramp_strat = getStrategy("System Input Apparent Power Phs B"); + static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib * 0.9f); + float In_Vcn = getPointValue(equipment, "System Input RMS C-N"); float In_Ic = getPointValue(equipment, "System Input RMS Current Phase C"); float In_PFc = getPointValue(equipment, "System Input Power Factor Phs C"); ramp_strat = getStrategy("System Input Power Phase C"); static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic); - ramp_strat = getStrategy("Bypass Power Phase C"); + ramp_strat = getStrategy("Bypass Input Power Phase C"); static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic); - ramp_strat = getStrategy("System Input Apparent Power Phase C"); - static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic * In_PFc); + ramp_strat = getStrategy("System Input Apparent Power Phs C"); + static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic * 0.9f); //Output strategies float Out_Vab = getPointValue(equipment, "System Output RMS A-B"); @@ -204,24 +204,24 @@ State* BypassState::update(Equipment* equipment) { float Out_PFa = getPointValue(equipment, "System Output Power Factor Phs A"); ramp_strat = getStrategy("System Output Power Phase A"); static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia); - ramp_strat = getStrategy("System Output Apparent Power Phase A"); - static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * Out_PFa); + ramp_strat = getStrategy("System Output Apparent Power Phs A"); + static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * 0.9f); float Out_Vbn = getPointValue(equipment, "System Output RMS B-N"); float Out_Ib = getPointValue(equipment, "System Output RMS Current Phase B"); float Out_PFb = getPointValue(equipment, "System Output Power Factor Phs B"); ramp_strat = getStrategy("System Output Power Phase B"); static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib); - ramp_strat = getStrategy("System Output Apparent Power Phase B"); - static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * Out_PFb); + ramp_strat = getStrategy("System Output Apparent Power Phs B"); + static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * 0.9f); float Out_Vcn = getPointValue(equipment, "System Output RMS C-N"); float Out_Ic = getPointValue(equipment, "System Output RMS Current Phase C"); float Out_PFc = getPointValue(equipment, "System Output Power Factor Phs C"); ramp_strat = getStrategy("System Output Power Phase C"); static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic); - ramp_strat = getStrategy("System Output Apparent Power Phase C"); - static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * Out_PFc); + ramp_strat = getStrategy("System Output Apparent Power Phs C"); + static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * 0.9f); float Battery_time = getPointValue(equipment, "Battery Time Remaining"); float Bat_Percent = Battery_time /4.80f; @@ -252,9 +252,10 @@ State* BypassState::update(Equipment* equipment) { template<> void BypassState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state - Serial.println("Enter Battery State..."); + Serial.println("Enter Bypass State..."); setPointValue(equipment, "UPS Loading Status", 4.0f); setPointValue(equipment, "UPS Battery Status2", 3.0f); + setPointValue(equipment, "Percentage Load", 0.0f); // You could also update a Modbus register to show the "standby" state } diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp index f55d498..94036b7 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp @@ -47,9 +47,9 @@ RunningState::RunningState() { addStrategy("System Input RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); addStrategy("System Input RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Input RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Input RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Input RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); addStrategy("System Input Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); @@ -57,13 +57,12 @@ RunningState::RunningState() { addStrategy("System Input Power Factor Phs B", new SingleValueStrategy(93.0F, 0.5f, 1000)); addStrategy("System Input Power Factor Phs C", new SingleValueStrategy(93.0F, 0.5f, 1000)); - addStrategy("System Input Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - + addStrategy("System Input Power Phase A", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase B", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase C", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Apparent Power Phs A", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Apparent Power Phs B", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Apparent Power Phs C", new RampStrategy(0.0F, 5.0f, 1000)); addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); @@ -71,29 +70,28 @@ RunningState::RunningState() { addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - - addStrategy("System Output RMS Current Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + + addStrategy("System Output RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Output RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Output RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); addStrategy("System Output Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); - + addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0F, 5.0f, 1000)); addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); - + addStrategy("System Output Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); addStrategy("System Output Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); addStrategy("System Output Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - - addStrategy("Battery Time Remaining", new RampStrategy(480.0F, 1.0f, 1000)); - - + addStrategy("System Output Apparent Power Phs A", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs B", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Apparent Power Phs C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("DC Bus Voltage", new SingleValueStrategy(518.0F, 5.0f, 1000)); - + addStrategy("Battery Time Remaining", new RampStrategy(480.0F, 1.0f, 1000)); + addStrategy("Percentage Load", new RampStrategy(100.0F, 1.0f, 1000)); + } /** @@ -149,24 +147,24 @@ State* RunningState::update(Equipment* equipment) float In_PFa = getPointValue(equipment, "System Input Power Factor Phs A"); ramp_strat = getStrategy("System Input Power Phase A"); static_cast(ramp_strat)->setTarget(In_Van * In_Ia); - ramp_strat = getStrategy("System Input Apparent Power Phase A"); - static_cast(ramp_strat)->setTarget(In_Van * In_Ia * (In_PFa/100.0f)); + ramp_strat = getStrategy("System Input Apparent Power Phs A"); + static_cast(ramp_strat)->setTarget(In_Van * In_Ia * 0.9f); float In_Vbn = getPointValue(equipment, "System Input RMS B-N"); float In_Ib = getPointValue(equipment, "System Input RMS Current Phase B"); float In_PFb = getPointValue(equipment, "System Input Power Factor Phs B"); ramp_strat = getStrategy("System Input Power Phase B"); static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib); - ramp_strat = getStrategy("System Input Apparent Power Phase B"); - static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib * (In_PFb/100.0f)); + ramp_strat = getStrategy("System Input Apparent Power Phs B"); + static_cast(ramp_strat)->setTarget(In_Vbn * In_Ib * 0.9f); float In_Vcn = getPointValue(equipment, "System Input RMS C-N"); float In_Ic = getPointValue(equipment, "System Input RMS Current Phase C"); float In_PFc = getPointValue(equipment, "System Input Power Factor Phs C"); ramp_strat = getStrategy("System Input Power Phase C"); static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic); - ramp_strat = getStrategy("System Input Apparent Power Phase C"); - static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic * (In_PFc/100.0f)); + ramp_strat = getStrategy("System Input Apparent Power Phs C"); + static_cast(ramp_strat)->setTarget(In_Vcn * In_Ic * 0.9f); //Output strategies float Out_Vab = getPointValue(equipment, "System Output RMS A-B"); @@ -184,24 +182,24 @@ State* RunningState::update(Equipment* equipment) float Out_PFa = getPointValue(equipment, "System Output Power Factor Phs A"); ramp_strat = getStrategy("System Output Power Phase A"); static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia); - ramp_strat = getStrategy("System Output Apparent Power Phase A"); - static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * (Out_PFa/100.0f)); + ramp_strat = getStrategy("System Output Apparent Power Phs A"); + static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * 0.9f); float Out_Vbn = getPointValue(equipment, "System Output RMS B-N"); float Out_Ib = getPointValue(equipment, "System Output RMS Current Phase B"); float Out_PFb = getPointValue(equipment, "System Output Power Factor Phs B"); ramp_strat = getStrategy("System Output Power Phase B"); static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib); - ramp_strat = getStrategy("System Output Apparent Power Phase B"); - static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * (Out_PFb/100.0f)); + ramp_strat = getStrategy("System Output Apparent Power Phs B"); + static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * 0.9f); float Out_Vcn = getPointValue(equipment, "System Output RMS C-N"); float Out_Ic = getPointValue(equipment, "System Output RMS Current Phase C"); float Out_PFc = getPointValue(equipment, "System Output Power Factor Phs C"); ramp_strat = getStrategy("System Output Power Phase C"); static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic); - ramp_strat = getStrategy("System Output Apparent Power Phase C"); - static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * (Out_PFc/100.0f)); + ramp_strat = getStrategy("System Output Apparent Power Phs C"); + static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * 0.9f); float Battery_time = getPointValue(equipment, "Battery Time Remaining"); float Bat_Percent = Battery_time /4.80f; diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Standby.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Standby.cpp index 3ce2bbd..602846b 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Standby.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Standby.cpp @@ -86,9 +86,60 @@ State* StandbyState::update(Equipment* equipment) */ template<> void StandbyState::enterState(Equipment* equipment) { - // Logic to run when the equipment enters this state - Serial.println("Enter Standby State..."); - setPointValue(equipment, "UPS Loading Status", 2.0f); + // Logic to run when the equipment enters this state + Serial.println("Enter Standby State..."); + setPointValue(equipment, "UPS Loading Status", 2.0f); + + setPointValue(equipment, "System Input RMS A-B", 0.0f); + setPointValue(equipment, "System Input RMS B-C", 0.0f); + setPointValue(equipment, "System Input RMS C-A", 0.0f); + setPointValue(equipment, "System Input RMS A-N", 0.0f); + setPointValue(equipment, "System Input RMS B-N", 0.0f); + setPointValue(equipment, "System Input RMS C-N", 0.0f); + setPointValue(equipment, "System Input RMS Current Phase A", 0.0f); + setPointValue(equipment, "System Input RMS Current Phase B", 0.0f); + setPointValue(equipment, "System Input RMS Current Phase C", 0.0f); + setPointValue(equipment, "System Input Frequency", 0.0f); + setPointValue(equipment, "System Input Power Factor Phs A", 0.0f); + setPointValue(equipment, "System Input Power Factor Phs B", 0.0f); + setPointValue(equipment, "System Input Power Factor Phs C", 0.0f); + setPointValue(equipment, "System Input Power Phase A", 0.0f); + setPointValue(equipment, "System Input Power Phase B", 0.0f); + setPointValue(equipment, "System Input Power Phase C", 0.0f); + setPointValue(equipment, "System Input Apparent Power Phs A", 0.0f); + setPointValue(equipment, "System Input Apparent Power Phs B", 0.0f); + setPointValue(equipment, "System Input Apparent Power Phs C", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS A-B", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS B-C", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS C-A", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS A-N", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS B-N", 0.0f); + setPointValue(equipment, "Bypass Input Voltage RMS C-N", 0.0f); + setPointValue(equipment, "Bypass Input Frequency", 0.0f); + setPointValue(equipment, "Bypass Power Phase A", 0.0f); + setPointValue(equipment, "Bypass Power Phase B", 0.0f); + setPointValue(equipment, "Bypass Power Phase C", 0.0f); + setPointValue(equipment, "System Output RMS A-B", 0.0f); + setPointValue(equipment, "System Output RMS B-C", 0.0f); + setPointValue(equipment, "System Output RMS C-A", 0.0f); + setPointValue(equipment, "System Output RMS A-N", 0.0f); + setPointValue(equipment, "System Output RMS B-N", 0.0f); + setPointValue(equipment, "System Output RMS C-N", 0.0f); + setPointValue(equipment, "System Output RMS Current Phase A", 0.0f); + setPointValue(equipment, "System Output RMS Current Phase B", 0.0f); + setPointValue(equipment, "System Output RMS Current Phase C", 0.0f); + setPointValue(equipment, "System Output Frequency", 0.0f); + setPointValue(equipment, "System Output Power Factor Phs A", 0.0f); + setPointValue(equipment, "System Output Power Factor Phs B", 0.0f); + setPointValue(equipment, "System Output Power Factor Phs C", 0.0f); + setPointValue(equipment, "System Output Power Phase A", 0.0f); + setPointValue(equipment, "System Output Power Phase B", 0.0f); + setPointValue(equipment, "System Output Power Phase C", 0.0f); + setPointValue(equipment, "System Output Apparent Power Phs A", 0.0f); + setPointValue(equipment, "System Output Apparent Power Phs B", 0.0f); + setPointValue(equipment, "System Output Apparent Power Phs C", 0.0f); + setPointValue(equipment, "System Output Power", 0.0f); + setPointValue(equipment, "System Output Apparent Power", 0.0f); } /** diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h index 766b749..9b11fce 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h @@ -23,8 +23,8 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 187); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 3, 187); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 3, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -125,7 +125,8 @@ modbusMap mb_map[] = {IR, 60, 0, "System Output Power"}, {IR, 61, 0, "System Output Apparent Power"}, {IR, 164, 0, "UPS Loading Status"}, - {IR, 175, 0, "DC Bus Voltage"}, + {IR, 175, 0, "DC Bus Voltage"}, + {IR, 179, 0, "Percentage Load"}, {IR, 180, 0, "Battery Time Remaining"}, {IR, 183, 0, "UPS Battery Status1"}, {IR, 184, 0, "UPS Battery Status2"}, From 39e70ca9ad623cd3644f91dcc64232e4555da76f Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Sat, 25 Oct 2025 10:19:16 -0500 Subject: [PATCH 02/51] s --- platformio.ini | 2 +- .../ATS/ATS_Eaton_ATC900_RPD_TCP/config.h | 8 +-- .../State_Running.cpp | 14 ++--- .../State_Standby.cpp | 3 ++ .../ATS/ATS_Woodward_DTSC200A_TCP/config.h | 2 +- .../PDU_Maverick_Power_TCP/State_Running.cpp | 51 ++++++++++++++++++- src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h | 8 +-- 7 files changed, 70 insertions(+), 18 deletions(-) diff --git a/platformio.ini b/platformio.ini index a11d920..8d5873a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,7 +11,7 @@ [platformio] -default_envs = PDU_Maverick_Power_TCP ; Select here the name of the configuration you want to download +default_envs = ATS_Eaton_ATC900_RPD_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM50 diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h index 867ffca..d5a84a6 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "wifi_ssid"; /**< @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, 15); /**< @brief The static IP address for the device. */ - IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */ + const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 33, 169); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp index 1ea1b5f..1378e38 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp @@ -39,9 +39,9 @@ template<> RunningState::RunningState() { - addStrategy("S2 Volts AB", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("S2 Volts BC", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("S2 Volts CA", new SingleValueStrategy(480.0F, 2.0f, 1000)); + addStrategy("S2 Volts AB", new SingleValueStrategy(4800.0F, 2.0f, 1000)); + addStrategy("S2 Volts BC", new SingleValueStrategy(4800.0F, 2.0f, 1000)); + addStrategy("S2 Volts CA", new SingleValueStrategy(4800.0F, 2.0f, 1000)); addStrategy("PF", new SingleValueStrategy(90.0f, 2.0f, 1000)); @@ -76,9 +76,9 @@ State* RunningState::update(Equipment* equipment) float volts_BC = getPointValue(equipment, "S2 Volts BC"); float volts_AC = getPointValue(equipment, "S2 Volts CA"); - setPointValue(equipment, "S2 Volts AN", volts_AB/1.732); - setPointValue(equipment, "S2 Volts BN", volts_BC/1.732); - setPointValue(equipment, "S2 Volts CN", volts_AC/1.732); + setPointValue(equipment, "S2 Volts AN", volts_AB/17.32); + setPointValue(equipment, "S2 Volts BN", volts_BC/17.32); + setPointValue(equipment, "S2 Volts CN", volts_AC/17.32); int I_load = getPointValue(equipment, "ATS_Load"); int I_rating = getPointValue(equipment, "ATS_Rating"); @@ -129,6 +129,8 @@ void RunningState::enterState(Equipment* equipment) { setPointValue(equipment, "S1 Amps A", 0.0f); setPointValue(equipment, "S1 Amps B", 0.0f); setPointValue(equipment, "S1 Amps C", 0.0f); + setBitValue(equipment, "Source Active", 3, true); + setBitValue(equipment, "Source Active", 4, false); } /** diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp index eadd167..f57063c 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp @@ -121,6 +121,9 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "S2 Amps A", 0.0f); setPointValue(equipment, "S2 Amps B", 0.0f); setPointValue(equipment, "S2 Amps C", 0.0f); + + setBitValue(equipment, "Source Active", 3, false); + setBitValue(equipment, "Source Active", 4, true); } /** diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h index 88f51c0..6a14e99 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 241); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 33, 173); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp index df33296..fe6aa68 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp @@ -224,8 +224,15 @@ State* RunningState::update(Equipment* equipment) tag = ""; tag = cb + "_L3KVar"; setPointValue(equipment, tag, total_load * 1715.0f * 0.9f); - - + tag = ""; + tag = cb + "_L1KVA"; + setPointValue(equipment, tag, total_load * 1715.0f); + tag = ""; + tag = cb + "_L2KVA"; + setPointValue(equipment, tag, total_load * 1715.0f); + tag = ""; + tag = cb + "_L3KVA"; + setPointValue(equipment, tag, total_load * 1715.0f); } else{ if (cb_status == 2.0f){ @@ -295,9 +302,49 @@ State* RunningState::update(Equipment* equipment) tag = ""; tag = cb + "_L3KVar"; setPointValue(equipment, tag, total_load*0.0f); + tag = ""; + tag = cb + "_L1KVA"; + setPointValue(equipment, tag, 0.0f); + tag = ""; + tag = cb + "_L2KVA"; + setPointValue(equipment, tag, 0.0f); + tag = ""; + tag = cb + "_L3KVA"; + setPointValue(equipment, tag, 0.0f); } cb_num++; + + float kw1 = getPointValue(equipment, cb + "_L1KW"); + float kw2 = getPointValue(equipment, cb + "_L2KW"); + float kw3 = getPointValue(equipment, cb + "_L3KW"); + tag = ""; + tag = cb + "_TotalKW"; + setPointValue(equipment, tag, kw1 + kw2 + kw3); + + float kvar1 = getPointValue(equipment, cb + "_L1KVar"); + float kvar2 = getPointValue(equipment, cb + "_L2KVar"); + float kvar3 = getPointValue(equipment, cb + "_L3KVar"); + tag = ""; + tag = cb + "_TotalKVar"; + setPointValue(equipment, tag, kvar1 + kvar2 + kvar3); + + float kva1 = getPointValue(equipment, cb + "_L1KVA"); + float kva2 = getPointValue(equipment, cb + "_L2KVA"); + float kva3 = getPointValue(equipment, cb + "_L3KVA"); + tag = ""; + tag = cb + "_TotalKVA"; + setPointValue(equipment, tag, kvar1 + kva2 + kva3); + + float pf1 = getPointValue(equipment, cb + "_L1PF"); + float pf2 = getPointValue(equipment, cb + "_L2PF"); + float pf3 = getPointValue(equipment, cb + "_L3PF"); + float total_pf = (pf1 + pf2 + pf3) / 3.0f; + tag = ""; + tag = cb + "_TotalPF"; + setPointValue(equipment, tag, total_pf); } + + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h index 3bb5f0c..57a6fce 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 181); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 33, 178); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -113,7 +113,7 @@ modbusMap mb_map[] = { {IR_LONG, 64, 0, "CB0_V31" }, {IR_LONG, 66, 0, "CB0_TotalKW" }, {IR_LONG, 68, 0, "CB0_TotalKVar" }, - {IR_LONG, 70, 0, "CB0_TotalKVA" }, + {IR_LONG, 70, 0, "CB0_TotalKVA" }, // {IR_LONG, 72, 0, "CB0_TotalPF" }, {IR_LONG, 74, 0, "CB0_TotalPFLag" }, {IR_LONG, 76, 0, "CB0_TotalPFLead" }, @@ -563,8 +563,8 @@ modbusMap mb_map[] = { {IR_FLOAT, 1087, 0, "kWh" }, {IR_FLOAT, 1091, 0, "PF" }, - {IR, 1150, 0, "CB_Status" }, - {IR, 1151, 0, "CB_Tripped" }, + {IR, 1550, 0, "CB_Status" }, + {IR, 1551, 0, "CB_Tripped" }, }; //Size of modbus map used in FOR cycles, automatically calculated. From 83a20282386e1f83c42316303ef8c116323c27b5 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Mon, 27 Oct 2025 08:07:59 -0500 Subject: [PATCH 03/51] 3 --- .../State_Running.cpp | 51 +- .../State_Standby.cpp | 61 +- .../ATS/ATS_Eaton_ATC900_RPD_TCP/config.h | 6 +- .../State_Running.cpp | 54 +- .../State_Standby.cpp | 46 +- .../ATS/ATS_Woodward_DTSC200A_TCP/config.h | 51 +- .../PDU_Maverick_Power_TCP/State_Running.cpp | 18 +- src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h | 649 +++++------------- 8 files changed, 327 insertions(+), 609 deletions(-) diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp index 4fab407..accba63 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp @@ -39,20 +39,19 @@ template<> RunningState::RunningState() { - addStrategy("Source 1 Volts AB", new SingleValueStrategy(0.0F, 0.0f, 1000)); - addStrategy("Source 1 Volts BC", new SingleValueStrategy(0.0F, 0.0f, 1000)); - addStrategy("Source 2 Volts CA", new SingleValueStrategy(0.0F, 0.0f, 1000)); addStrategy("Source 2 Volts AB", new SingleValueStrategy(480.0F, 2.0f, 1000)); addStrategy("Source 2 Volts BC", new SingleValueStrategy(480.0F, 2.0f, 1000)); addStrategy("Source 2 Volts CA", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("Source 1 Frequency", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Source 2 Frequency", new SingleValueStrategy(60.0f, 1.0f, 1000)); - addStrategy("Power Factor", new SingleValueStrategy(90.0f, 2.0f, 1000)); - - 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)); + addStrategy("Volts AB", new SingleValueStrategy(480.0f, 2.0f, 1000)); + addStrategy("Votls BC", new SingleValueStrategy(480.0f, 2.0f, 1000)); + addStrategy("Volts CA", new SingleValueStrategy(480.0f, 2.0f, 1000)); + addStrategy("Amps A", new SingleValueStrategy(1.0f, 3.0f, 1000)); + addStrategy("Amps B", new SingleValueStrategy(1.0f, 3.0f, 1000)); + addStrategy("Amps C", new SingleValueStrategy(1.0f, 3.0f, 1000)); + addStrategy("Total Active Power", new SingleValueStrategy(6.0f, 5.0f, 1000)); + addStrategy("Total Apparent Power", new SingleValueStrategy(6.0f, 5.0f, 1000)); } @@ -78,20 +77,31 @@ State* RunningState::update(Equipment* equipment) return new StandbyState(); } - int I_load = getPointValue(equipment, "ATS_Load"); - int I_rating = getPointValue(equipment, "ATS_Rating"); - float load = static_cast(I_load); - float rating = static_cast(I_rating); - float real_load = rating * (load/100.0f); + float load = getPointValue(equipment, "ATS_Load"); + float rating = getPointValue(equipment, "ATS_Rating"); + float sim_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); - + static_cast(ampsA_svs)->setSetpoint(sim_load); + static_cast(ampsB_svs)->setSetpoint(sim_load); + static_cast(ampsC_svs)->setSetpoint(sim_load); // Apply any strategies defined for the standby state + float v_ab = getPointValue(equipment, "Source 2 Volts AB"); + float v_bc = getPointValue(equipment, "Source 2 Volts BC"); + float v_ca = getPointValue(equipment, "Source 2 Volts CA"); + float i_a = getPointValue(equipment, "Amps A"); + float i_b = getPointValue(equipment, "Amps B"); + float i_c = getPointValue(equipment, "Ampc C"); + float pwr = ((v_ab * i_a) + (v_bc * i_b) + (v_ca * i_c)); + setPointValue(equipment, "Total Active Power", pwr*1000.0f); + float pf = getPointValue(equipment, "Power Factor"); + float a_pwr = pwr * (pf/100.0f); + setPointValue(equipment, "Total Apparent Power", a_pwr*1000.0f); + + _applyStrategies(equipment); return nullptr; } @@ -113,6 +123,11 @@ void RunningState::enterState(Equipment* equipment) { setPointValue(equipment, "Source 1 Preferred", 1); setPointValue(equipment, "Source 2 Preferred", 0); + setPointValue(equipment, "Source 1 Volts AB", 0.0f); + setPointValue(equipment, "Source 1 Volts BC", 0.0f); + setPointValue(equipment, "Source 1 Volts CA", 0.0f); + setPointValue(equipment, "Source 1 Frequency", 0.0f); + int transferQty = getPointValue(equipment, "Number of Transfers"); setPointValue(equipment, "Number of Transfers", transferQty + 1); } diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp index be9fef9..39347b3 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp @@ -37,21 +37,21 @@ */ template<> StandbyState::StandbyState() { - // You can add initialization code here if needed - addStrategy("Source 1 Volts AB", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("Source 1 Volts BC", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("Source 1 Volts CA", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("Source 2 Volts AB", new SingleValueStrategy(0.0F, 0.0f, 1000)); - addStrategy("Source 2 Volts BC", new SingleValueStrategy(0.0F, 0.0f, 1000)); - addStrategy("Source 2 Volts CA", new SingleValueStrategy(0.0F, 0.0f, 1000)); - addStrategy("Source 1 Frequency", new SingleValueStrategy(60.0f, 1.0f, 1000)); - addStrategy("Source 2 Frequency", new SingleValueStrategy(0.0f, 0.0f, 1000)); + // You can add initialization code here if needed + addStrategy("Source 1 Volts AB", new SingleValueStrategy(480.0F, 2.0f, 1000)); + addStrategy("Source 1 Volts BC", new SingleValueStrategy(480.0F, 2.0f, 1000)); + addStrategy("Source 1 Volts CA", new SingleValueStrategy(480.0F, 2.0f, 1000)); + addStrategy("Source 1 Frequency", new SingleValueStrategy(60.0f, 1.0f, 1000)); + addStrategy("Power Factor", new SingleValueStrategy(90.0f, 2.0f, 1000)); + addStrategy("Volts AB", new SingleValueStrategy(480.0f, 2.0f, 1000)); + addStrategy("Votls BC", new SingleValueStrategy(480.0f, 2.0f, 1000)); + addStrategy("Volts CA", new SingleValueStrategy(480.0f, 2.0f, 1000)); + addStrategy("Amps A", new SingleValueStrategy(1.0f, 3.0f, 1000)); + addStrategy("Amps B", new SingleValueStrategy(1.0f, 3.0f, 1000)); + addStrategy("Amps C", new SingleValueStrategy(1.0f, 3.0f, 1000)); + addStrategy("Total Active Power", new SingleValueStrategy(6.0f, 5.0f, 1000)); + addStrategy("Total Apparent Power", new SingleValueStrategy(6.0f, 5.0f, 1000)); - addStrategy("Power Factor", new SingleValueStrategy(90.0f, 2.0f, 1000)); - - 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)); } /** @@ -73,19 +73,31 @@ State* StandbyState::update(Equipment* equipment) return new RunningState(); } - int I_load = getPointValue(equipment, "ATS_Load"); - int I_rating = getPointValue(equipment, "ATS_Rating"); - float load = static_cast(I_load); - float rating = static_cast(I_rating); - float real_load = rating * (load/100.0f); + float load = getPointValue(equipment, "ATS_Load"); + float rating = getPointValue(equipment, "ATS_Rating"); + float sim_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); + static_cast(ampsA_svs)->setSetpoint(sim_load); + static_cast(ampsB_svs)->setSetpoint(sim_load); + static_cast(ampsC_svs)->setSetpoint(sim_load); // Apply any strategies defined for the standby state + float v_ab = getPointValue(equipment, "Source 1 Volts AB"); + float v_bc = getPointValue(equipment, "Source 1 Volts BC"); + float v_ca = getPointValue(equipment, "Source 1 Volts CA"); + float i_a = getPointValue(equipment, "Amps A"); + float i_b = getPointValue(equipment, "Amps B"); + float i_c = getPointValue(equipment, "Ampc C"); + float pwr = ((v_ab * i_a) + (v_bc * i_b) + (v_ca * i_c)); + setPointValue(equipment, "Total Active Power", pwr*1000.0f); + float pf = getPointValue(equipment, "Power Factor"); + float a_pwr = pwr * (pf/100.0f); + setPointValue(equipment, "Total Apparent Power", a_pwr*1000.0f); + + _applyStrategies(equipment); return nullptr; } @@ -107,6 +119,11 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "Source 1 Preferred", 0); setPointValue(equipment, "Source 2 Preferred", 1); + setPointValue(equipment, "Source 2 Volts AB", 0.0f); + setPointValue(equipment, "Source 2 Volts BC", 0.0f); + setPointValue(equipment, "Source 2 Volts CA", 0.0f); + setPointValue(equipment, "Source 2 Frequency", 0.0f); + int transferQty = getPointValue(equipment, "Number of Transfers"); setPointValue(equipment, "Number of Transfers", transferQty + 1); } diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h index d5a84a6..65b58f6 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h @@ -86,9 +86,9 @@ modbusMap mb_map[] = {IR, 6158, 0, "Amps A"}, {IR, 6159, 0, "Amps B"}, {IR, 6160, 0, "Amps C"}, - {IR_LONG, 6165, 0, "Total Active Power"}, - {IR_LONG, 6169, 0, "Total Apparent Power"}, - {IR, 6171, 0, "Power Factor"}, + {IR_LONG, 6165, 0, "Total Active Power"}, //0.001 + {IR_LONG, 6169, 0, "Total Apparent Power"}, //0.001 + {IR, 6171, 0, "Power Factor"}, //0.001 {IR, 6263, 0, "Number of Transfers"}, {IR, 6297, 0, "Alarm Status Bits"}, diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp index 1378e38..9dafbf6 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp @@ -39,15 +39,15 @@ template<> RunningState::RunningState() { - addStrategy("S2 Volts AB", new SingleValueStrategy(4800.0F, 2.0f, 1000)); - addStrategy("S2 Volts BC", new SingleValueStrategy(4800.0F, 2.0f, 1000)); - addStrategy("S2 Volts CA", new SingleValueStrategy(4800.0F, 2.0f, 1000)); + addStrategy("S2 Volts AB", new SingleValueStrategy(4800.0F, 10.0f, 1000)); + addStrategy("S2 Volts BC", new SingleValueStrategy(4800.0F, 10.0f, 1000)); + addStrategy("S2 Volts CA", new SingleValueStrategy(4800.0F, 10.0f, 1000)); - addStrategy("PF", new SingleValueStrategy(90.0f, 2.0f, 1000)); + addStrategy("PF", new SingleValueStrategy(910.0f, 20.0f, 1000)); - addStrategy("S2 Amps A", new SingleValueStrategy(1.0f, 5.0f, 1000)); - addStrategy("S2 Amps B", new SingleValueStrategy(1.0f, 5.0f, 1000)); - addStrategy("S2 Amps C", new SingleValueStrategy(1.0f, 5.0f, 1000)); + addStrategy("S2 Amps A", new SingleValueStrategy(200.0f, 100.0f, 1000)); + addStrategy("S2 Amps B", new SingleValueStrategy(200.0f, 100.0f, 1000)); + addStrategy("S2 Amps C", new SingleValueStrategy(200.0f, 100.0f, 1000)); } @@ -74,33 +74,36 @@ State* RunningState::update(Equipment* equipment) } float volts_AB = getPointValue(equipment, "S2 Volts AB"); float volts_BC = getPointValue(equipment, "S2 Volts BC"); - float volts_AC = getPointValue(equipment, "S2 Volts CA"); + float volts_CA = getPointValue(equipment, "S2 Volts CA"); - setPointValue(equipment, "S2 Volts AN", volts_AB/17.32); - setPointValue(equipment, "S2 Volts BN", volts_BC/17.32); - setPointValue(equipment, "S2 Volts CN", volts_AC/17.32); + setPointValue(equipment, "S2 Volts AN", volts_AB/1.732); + setPointValue(equipment, "S2 Volts BN", volts_BC/1.732); + setPointValue(equipment, "S2 Volts CN", volts_CA/1.732); int I_load = getPointValue(equipment, "ATS_Load"); int I_rating = getPointValue(equipment, "ATS_Rating"); float load = static_cast(I_load); float rating = static_cast(I_rating); - float real_load = rating * (load/100.0f); + float sim_load = rating * (load/100.0f); Strategy_Behavior* ampsA_svs = getStrategy("S2 Amps A"); Strategy_Behavior* ampsB_svs = getStrategy("S2 Amps B"); Strategy_Behavior* ampsC_svs = getStrategy("S2 Amps C"); - static_cast(ampsA_svs)->setSetpoint(real_load); - static_cast(ampsB_svs)->setSetpoint(real_load); - static_cast(ampsC_svs)->setSetpoint(real_load); + static_cast(ampsA_svs)->setSetpoint(sim_load*1000.0f); + static_cast(ampsB_svs)->setSetpoint(sim_load*1000.0f); + static_cast(ampsC_svs)->setSetpoint(sim_load*1000.0f); - float pf = getPointValue(equipment, "PF"); + float get_pf = getPointValue(equipment, "PF"); + float pf = get_pf/1000.0f; - - 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; + float real_v_AB = volts_AB/1000.0f; + float real_v_BC = volts_BC/1000.0f; + float real_v_CA = volts_CA/1000.0f; + float kw = (1.732f * ((real_v_AB + real_v_BC + real_v_CA)/3.0f) * sim_load * pf)*10; + float mwh = kw *600.0f; setPointValue(equipment, "S2 kW", kw); - setPointValue(equipment, "S2 kVA", kva); + setPointValue(equipment, "S2 MWh", mwh); // Apply any strategies defined for the standby state _applyStrategies(equipment); @@ -117,9 +120,6 @@ 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, "Source Active", 32); - setPointValue(equipment, "Source Preferred", 512); - setPointValue(equipment, "S1 Volts AB", 0.0f); setPointValue(equipment, "S1 Volts BC", 0.0f); setPointValue(equipment, "S1 Volts CA", 0.0f); @@ -129,8 +129,14 @@ void RunningState::enterState(Equipment* equipment) { setPointValue(equipment, "S1 Amps A", 0.0f); setPointValue(equipment, "S1 Amps B", 0.0f); setPointValue(equipment, "S1 Amps C", 0.0f); - setBitValue(equipment, "Source Active", 3, true); + setPointValue(equipment, "S1 kW", 0.0f); + setPointValue(equipment, "S1 MWh", 0.0f); + setBitValue(equipment, "Source Active", 4, false); + setBitValue(equipment, "Source Active", 3, true); + + setBitValue(equipment, "Source Preferred", 8, false); + setBitValue(equipment, "Source Preferred", 9, true); } /** diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp index f57063c..10fd829 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp @@ -38,15 +38,15 @@ template<> StandbyState::StandbyState() { // You can add initialization code here if needed - addStrategy("S1 Volts AB", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("S1 Volts BC", new SingleValueStrategy(480.0F, 2.0f, 1000)); - addStrategy("S1 Volts CA", new SingleValueStrategy(480.0F, 2.0f, 1000)); + addStrategy("S1 Volts AB", new SingleValueStrategy(4800.0F, 10.0f, 1000)); + addStrategy("S1 Volts BC", new SingleValueStrategy(4800.0F, 10.0f, 1000)); + addStrategy("S1 Volts CA", new SingleValueStrategy(4800.0F, 10.0f, 1000)); - addStrategy("PF", new SingleValueStrategy(90.0f, 2.0f, 1000)); + addStrategy("PF", new SingleValueStrategy(910.0f, 20.0f, 1000)); - addStrategy("S1 Amps A", new SingleValueStrategy(1.0f, 5.0f, 1000)); - addStrategy("S1 Amps B", new SingleValueStrategy(1.0f, 5.0f, 1000)); - addStrategy("S1 Amps C", new SingleValueStrategy(1.0f, 5.0f, 1000)); + addStrategy("S1 Amps A", new SingleValueStrategy(200.0f, 100.0f, 1000)); + addStrategy("S1 Amps B", new SingleValueStrategy(200.0f, 100.0f, 1000)); + addStrategy("S1 Amps C", new SingleValueStrategy(200.0f, 100.0f, 1000)); } /** @@ -68,33 +68,36 @@ State* StandbyState::update(Equipment* equipment) } float volts_AB = getPointValue(equipment, "S1 Volts AB"); float volts_BC = getPointValue(equipment, "S1 Volts BC"); - float volts_AC = getPointValue(equipment, "S1 Volts CA"); + float volts_CA = getPointValue(equipment, "S1 Volts CA"); setPointValue(equipment, "S1 Volts AN", volts_AB/1.732); setPointValue(equipment, "S1 Volts BN", volts_BC/1.732); - setPointValue(equipment, "S1 Volts CN", volts_AC/1.732); + setPointValue(equipment, "S1 Volts CN", volts_CA/1.732); int I_load = getPointValue(equipment, "ATS_Load"); int I_rating = getPointValue(equipment, "ATS_Rating"); float load = static_cast(I_load); float rating = static_cast(I_rating); - float real_load = rating * (load/100.0f); + float sim_load = rating * (load/100.0f); Strategy_Behavior* ampsA_svs = getStrategy("S1 Amps A"); Strategy_Behavior* ampsB_svs = getStrategy("S1 Amps B"); Strategy_Behavior* ampsC_svs = getStrategy("S1 Amps C"); - static_cast(ampsA_svs)->setSetpoint(real_load); - static_cast(ampsB_svs)->setSetpoint(real_load); - static_cast(ampsC_svs)->setSetpoint(real_load); + static_cast(ampsA_svs)->setSetpoint(sim_load*1000.0f); + static_cast(ampsB_svs)->setSetpoint(sim_load*1000.0f); + static_cast(ampsC_svs)->setSetpoint(sim_load*1000.0f); - float pf = getPointValue(equipment, "PF"); + float get_pf = getPointValue(equipment, "PF"); + float pf = get_pf/1000.0f; - - 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; + float real_v_AB = volts_AB/1000.0f; + float real_v_BC = volts_BC/1000.0f; + float real_v_CA = volts_CA/1000.0f; + float kw = (1.732f * ((real_v_AB + real_v_BC + real_v_CA)/3.0f) * sim_load * pf)*10; + float mwh = kw *600.0f; setPointValue(equipment, "S1 kW", kw); - setPointValue(equipment, "S1 kVA", kva); + setPointValue(equipment, "S1 MWh", mwh); _applyStrategies(equipment); return nullptr; } @@ -109,8 +112,6 @@ template<> void StandbyState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Standby State..."); - setPointValue(equipment, "Source Active", 64); - setPointValue(equipment, "Source Preferred", 1024); setPointValue(equipment, "S2 Volts AB", 0.0f); setPointValue(equipment, "S2 Volts BC", 0.0f); @@ -121,9 +122,14 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "S2 Amps A", 0.0f); setPointValue(equipment, "S2 Amps B", 0.0f); setPointValue(equipment, "S2 Amps C", 0.0f); + setPointValue(equipment, "S2 kW", 0.0f); + setPointValue(equipment, "S2 MWh", 0.0f); setBitValue(equipment, "Source Active", 3, false); setBitValue(equipment, "Source Active", 4, true); + + setBitValue(equipment, "Source Preferred", 8, false); + setBitValue(equipment, "Source Preferred", 9, true); } /** diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h index 6a14e99..7b5d59e 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h @@ -64,31 +64,32 @@ modbusMap mb_map[] = {HR, 10, 0, "ATS_Load"}, {HR, 11, 0, "ATS_Rating"}, //Internal Fault code from Modscan - {HR, 50009, 0, "PF"}, - {HR_LONG, 50001, 0, "S2 Volts AB"}, - {HR_LONG, 50004, 0, "S2 Volts AN"}, - {HR_LONG, 50007, 0, "S2 Volts BC"}, - {HR_LONG, 50010, 0, "S2 Volts BN"}, - {HR_LONG, 50013, 0, "S2 Volts CA"}, - {HR_LONG, 50016, 0, "S2 Volts CN"}, - {HR_LONG, 50019, 0, "S1 Volts AB"}, - {HR_LONG, 50022, 0, "S1 Volts AN"}, - {HR_LONG, 50025, 0, "S1 Volts BC"}, - {HR_LONG, 50028, 0, "S1 Volts BN"}, - {HR_LONG, 50031, 0, "S1 Volts CA"}, - {HR_LONG, 50034, 0, "S1 Volts CN"}, - {HR_LONG, 50037, 0, "S2 Amps A"}, - {HR_LONG, 50040, 0, "S2 Amps B"}, - {HR_LONG, 50043, 0, "S2 Amps C"}, - {HR_LONG, 50060, 0, "S2 kW"}, - {HR_LONG, 50064, 0, "S2 MWh"}, - {HR, 50078, 0, "Source Preferred"}, // bit 8 and bit 9 - {HR, 50082, 0, "Source Active"}, //bit2 and bit 3 - {HR_LONG, 50091, 0, "S1 Amps A"}, - {HR, 50093, 0, "S1 kW"}, - {HR_LONG, 50094, 0, "S1 Amps B"}, - {HR_LONG, 50097, 0, "S1 Amps C"}, - {HR_LONG, 50100, 0, "S1 MWh"}, + {HR, 50009, 0, "PF"}, //0.001x + {HR_LONG, 50001, 0, "S2 Volts AB"}, //0.1x + {HR_LONG, 50004, 0, "S2 Volts AN"}, //0.1x + {HR_LONG, 50007, 0, "S2 Volts BC"}, //0.1x + {HR_LONG, 50010, 0, "S2 Volts BN"}, //0.1x + {HR_LONG, 50013, 0, "S2 Volts CA"}, //0.1x + {HR_LONG, 50016, 0, "S2 Volts CN"}, //0.1x + {HR_LONG, 50019, 0, "S1 Volts AB"}, //0.1x + {HR_LONG, 50022, 0, "S1 Volts AN"}, //0.1x + {HR_LONG, 50025, 0, "S1 Volts BC"}, //0.1x + {HR_LONG, 50028, 0, "S1 Volts BN"}, //0.1x + {HR_LONG, 50031, 0, "S1 Volts CA"}, //0.1x + {HR_LONG, 50034, 0, "S1 Volts CN"}, //0.1x + {HR_LONG, 50037, 0, "S2 Amps A"}, //0.001x + {HR_LONG, 50040, 0, "S2 Amps B"}, //0.001x + {HR_LONG, 50043, 0, "S2 Amps C"}, //0.001x + {HR_LONG, 50060, 0, "S2 kW"}, + {HR_LONG, 50064, 0, "S2 MWh"}, //0.01x + {HR, 50078, 0, "Source Preferred"}, //bit9 source1 bit8 source 2 + {HR, 50082, 0, "Source Active"}, //bit4 source1 bit3 source 2 + {HR_LONG, 50091, 0, "S1 Amps A"}, //.001x + {HR, 50093, 0, "S1 kW"}, //.1x + {HR_LONG, 50094, 0, "S1 Amps B"}, //.001x + {HR_LONG, 50097, 0, "S1 Amps C"}, //.001x + {HR_LONG, 50100, 0, "S1 MWh"}, //.01x + }; //Size of modbus map used in FOR cycles, automatically calculated. diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp index fe6aa68..c3e5fca 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp @@ -36,29 +36,21 @@ * state, such as a PID controller for the 'CW Valve Position' and totalizers * for the run-hours of each EC fan. */ -std::string cbs[] = {"CB0", "CB1", "CB2", "CB3", "CB4", "CB5", "CB6", "CB7", "CB8", "CB9"}; +std::string cbs[] = {"CB1", "CB2", "CB3", "CB4", "CB5", "CB6", "CB7", "CB8"}; template<> RunningState::RunningState() { for (const std::string& cb : cbs) { std::string tag = ""; tag = cb + "_V1N"; - addStrategy(tag, new SingleValueStrategy(0.0f, 30.0f, 1000)); + addStrategy(tag, new SingleValueStrategy(40.0f, 30.0f, 1000)); tag = ""; tag = cb + "_V2N"; - addStrategy(tag, new SingleValueStrategy(0.0f, 30.0f, 1000)); + addStrategy(tag, new SingleValueStrategy(40.0f, 30.0f, 1000)); tag = ""; tag = cb + "_V3N"; - addStrategy(tag, new SingleValueStrategy(0.0f, 30.0f, 1000)); - tag = ""; - tag = cb + "_L1PF"; - addStrategy(tag, new SingleValueStrategy(93.0f, 9.0f, 1000)); - tag = ""; - tag = cb + "_L2PF"; - addStrategy(tag, new SingleValueStrategy(93.0f, 9.0f, 1000)); - tag = ""; - tag = cb + "_L3PF"; - addStrategy(tag, new SingleValueStrategy(93.0f, 9.0f, 1000)); + addStrategy(tag, new SingleValueStrategy(40.0f, 30.0f, 1000)); + tag = ""; tag = cb + "_V1THD"; addStrategy(tag, new SingleValueStrategy(20.0f, 7.0f, 1000)); diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h index 57a6fce..f601499 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h @@ -64,9 +64,9 @@ modbusMap mb_map[] = { // Write Registers (as Input Registers - 3X) //*************************************** {HR, 9, 0, "Px Ctrl"}, - {HR, 10, 0, "Px Rating"}, //Watts + {HR, 10, 0, "Px Rating"}, //Amps {HR, 11, 0, "Px Load"}, //%load - {HR, 19, 0, "Px_CB0"}, + {HR, 19, 0, "Px_Input"}, {HR, 20, 0, "Px_CB1"}, {HR, 21, 0, "Px_CB2"}, {HR, 22, 0, "Px_CB3"}, @@ -75,497 +75,178 @@ modbusMap mb_map[] = { {HR, 25, 0, "Px_CB6"}, {HR, 26, 0, "Px_CB7"}, {HR, 27, 0, "Px_CB8"}, - {HR, 28, 0, "Px_CB9"}, + {HR, 28, 0, "Px_Output"}, - // System Status - {IR_LONG, 0, 0, "CB0_V1N" }, - {IR_LONG, 2, 0, "CB0_V2N" }, - {IR_LONG, 4, 0, "CB0_V3N" }, - {IR_LONG, 6, 0, "CB0_I1" }, - {IR_LONG, 8, 0, "CB0_I2" }, - {IR_LONG, 10, 0, "CB0_I3" }, - {IR_LONG, 12, 0, "CB0_L1KW" }, - {IR_LONG, 14, 0, "CB0_L2KW" }, - {IR_LONG, 16, 0, "CB0_L3KW" }, - {IR_LONG, 18, 0, "CB0_L1KVar" }, - {IR_LONG, 20, 0, "CB0_L2KVar" }, - {IR_LONG, 22, 0, "CB0_L3KVar" }, - {IR_LONG, 24, 0, "CB0_L1KVA" }, - {IR_LONG, 26, 0, "CB0_L2KVA" }, - {IR_LONG, 28, 0, "CB0_L3KVA" }, - {IR_LONG, 30, 0, "CB0_L1PF" }, - {IR_LONG, 32, 0, "CB0_L2PF" }, - {IR_LONG, 34, 0, "CB0_L3PF" }, - {IR_LONG, 36, 0, "CB0_V1THD" }, - {IR_LONG, 38, 0, "CB0_V2THD" }, - {IR_LONG, 40, 0, "CB0_V3THD" }, - {IR_LONG, 42, 0, "CB0_I1THD" }, - {IR_LONG, 44, 0, "CB0_I2THD" }, - {IR_LONG, 46, 0, "CB0_I3THD" }, - {IR_LONG, 48, 0, "CB0_I1Kfactor" }, - {IR_LONG, 50, 0, "CB0_I2Kfactor" }, - {IR_LONG, 52, 0, "CB0_I3Kfactor" }, - {IR_LONG, 54, 0, "CB0_I1TDD" }, - {IR_LONG, 56, 0, "CB0_I2TDD" }, - {IR_LONG, 58, 0, "CB0_I3TDD" }, - {IR_LONG, 60, 0, "CB0_V12" }, - {IR_LONG, 62, 0, "CB0_V23" }, - {IR_LONG, 64, 0, "CB0_V31" }, - {IR_LONG, 66, 0, "CB0_TotalKW" }, - {IR_LONG, 68, 0, "CB0_TotalKVar" }, - {IR_LONG, 70, 0, "CB0_TotalKVA" }, // - {IR_LONG, 72, 0, "CB0_TotalPF" }, - {IR_LONG, 74, 0, "CB0_TotalPFLag" }, - {IR_LONG, 76, 0, "CB0_TotalPFLead" }, - {IR_LONG, 78, 0, "CB0_TotalKWImport" }, - {IR_LONG, 80, 0, "CB0_TotalKWExport" }, - {IR_LONG, 82, 0, "CB0_TotalKVarImport" }, - {IR_LONG, 84, 0, "CB0_TotalKVarExport" }, - {IR_LONG, 86, 0, "CB0_LN_Avg" }, - {IR_LONG, 88, 0, "CB0_LL_Avg" }, - {IR_LONG, 92, 0, "CB0_TotalKWh" }, - {IR_LONG, 99, 0, "CB0_Status" }, + // PDU Input + {IR_LONG, 6, 0, "Input_I1" }, //0.01 + {IR_LONG, 8, 0, "Input_I2" }, //0.01 + {IR_LONG, 10, 0, "Input_I3" }, //0.01 + {IR_LONG, 70, 0, "Input_kVA" }, //0.001 + {IR_LONG, 68, 0, "Input_KVAR" }, //0.001 + {IR_LONG, 66, 0, "Input_kW" }, //0.001 + {IR_LONG, 66, 0, "Input_kWh" }, //0.1 + {IR_LONG, 72, 0, "Input_PF" }, //0.001 + {IR_LONG, 60, 0, "Input_V_AB" }, //0.1 + {IR_LONG, 0, 0, "Input_V_AN" }, //0.1 + {IR_LONG, 62, 0, "Input_V_BC" }, //0.1 + {IR_LONG, 2, 0, "Input_V_BN" }, //0.1 + {IR_LONG, 64, 0, "Input_V_CA" }, //0.1 + {IR_LONG, 4, 0, "Input_V_CN" }, //0.1 + {IR_LONG, 88, 0, "Input_LL_Avg" },//0.1 + {IR_LONG, 86, 0, "Input_LN_Avg" },//0.1 + + // Circuit Breaker 1 (CB1) + {IR_LONG, 106, 0, "CB1_I1" }, //0.01x + {IR_LONG, 108, 0, "CB1_I2" }, //0.01x + {IR_LONG, 110, 0, "CB1_I3" }, //0.01x + {IR_LONG, 170, 0, "CB1_kVA" }, //0.001x + {IR_LONG, 124, 0, "CB1_kVA1" }, //0.001x + {IR_LONG, 126, 0, "CB1_kVA2" }, //0.001x + {IR_LONG, 128, 0, "CB1_kVA3" }, //0.001x + {IR_LONG, 168, 0, "CB1_kVAR" }, //0.001x + {IR_LONG, 166, 0, "CB1_kW" }, //0.001x + {IR_LONG, 112, 0, "CB1_kW1" }, //0.001x + {IR_LONG, 114, 0, "CB1_kW2" }, //0.001x + {IR_LONG, 116, 0, "CB1_kW3" }, //0.001x + {IR_LONG, 1113, 0, "CB1_kWh" }, + {IR_LONG, 172, 0, "CB1_PF" }, //0.001x - // Circuit Breaker 1 (OB01) - {IR_LONG, 100, 0, "CB1_V1N" }, - {IR_LONG, 102, 0, "CB1_V2N" }, - {IR_LONG, 104, 0, "CB1_V3N" }, - {IR_LONG, 106, 0, "CB1_I1" }, - {IR_LONG, 108, 0, "CB1_I2" }, - {IR_LONG, 110, 0, "CB1_I3" }, - {IR_LONG, 112, 0, "CB1_L1KW" }, - {IR_LONG, 114, 0, "CB1_L2KW" }, - {IR_LONG, 116, 0, "CB1_L3KW" }, - {IR_LONG, 118, 0, "CB1_L1KVar" }, - {IR_LONG, 120, 0, "CB1_L2KVar" }, - {IR_LONG, 122, 0, "CB1_L3KVar" }, - {IR_LONG, 124, 0, "CB1_L1KVA" }, - {IR_LONG, 126, 0, "CB1_L2KVA" }, - {IR_LONG, 128, 0, "CB1_L3KVA" }, - {IR_LONG, 130, 0, "CB1_L1PF" }, - {IR_LONG, 132, 0, "CB1_L2PF" }, - {IR_LONG, 134, 0, "CB1_L3PF" }, - {IR_LONG, 136, 0, "CB1_V1THD" }, - {IR_LONG, 138, 0, "CB1_V2THD" }, - {IR_LONG, 140, 0, "CB1_V3THD" }, - {IR_LONG, 142, 0, "CB1_I1THD" }, - {IR_LONG, 144, 0, "CB1_I2THD" }, - {IR_LONG, 146, 0, "CB1_I3THD" }, - {IR_LONG, 148, 0, "CB1_I1Kfactor" }, - {IR_LONG, 150, 0, "CB1_I2Kfactor" }, - {IR_LONG, 152, 0, "CB1_I3Kfactor" }, - {IR_LONG, 154, 0, "CB1_I1TDD" }, - {IR_LONG, 156, 0, "CB1_I2TDD" }, - {IR_LONG, 158, 0, "CB1_I3TDD" }, - {IR_LONG, 160, 0, "CB1_V12" }, - {IR_LONG, 162, 0, "CB1_V23" }, - {IR_LONG, 164, 0, "CB1_V31" }, - {IR_LONG, 166, 0, "CB1_TotalKW" }, - {IR_LONG, 168, 0, "CB1_TotalKVar" }, - {IR_LONG, 170, 0, "CB1_TotalKVA" }, - {IR_LONG, 172, 0, "CB1_TotalPF" }, - {IR_LONG, 174, 0, "CB1_TotalPFLag" }, - {IR_LONG, 176, 0, "CB1_TotalPFLead" }, - {IR_LONG, 178, 0, "CB1_TotalKWImport" }, - {IR_LONG, 180, 0, "CB1_TotalKWExport" }, - {IR_LONG, 182, 0, "CB1_TotalKVarImport" }, - {IR_LONG, 184, 0, "CB1_TotalKVarExport" }, - {IR_LONG, 186, 0, "CB1_LN_Avg" }, - {IR_LONG, 188, 0, "CB1_LL_Avg" }, - {IR_LONG, 199, 0, "CB1_Status" }, + // Circuit Breaker 2 (CB1) + {IR_LONG, 206, 0, "CB2_I1" }, //0.01x + {IR_LONG, 208, 0, "CB2_I2" }, //0.01x + {IR_LONG, 210, 0, "CB2_I3" }, //0.01x + {IR_LONG, 270, 0, "CB2_kVA" }, //0.001x + {IR_LONG, 224, 0, "CB2_kVA1" }, //0.001x + {IR_LONG, 226, 0, "CB2_kVA2" }, //0.001x + {IR_LONG, 228, 0, "CB2_kVA3" }, //0.001x + {IR_LONG, 268, 0, "CB2_kVAR" }, //0.001x + {IR_LONG, 266, 0, "CB2_kW" }, //0.001x + {IR_LONG, 212, 0, "CB2_kW1" }, //0.001x + {IR_LONG, 214, 0, "CB2_kW2" }, //0.001x + {IR_LONG, 216, 0, "CB2_kW3" }, //0.001x + {IR_LONG, 1168, 0, "CB2_kWh" }, + {IR_LONG, 272, 0, "CB2_PF" }, //0.001x - // Circuit Breaker 2 (OB02) - {IR_LONG, 200, 0, "CB2_V1N" }, - {IR_LONG, 202, 0, "CB2_V2N" }, - {IR_LONG, 204, 0, "CB2_V3N" }, - {IR_LONG, 206, 0, "CB2_I1" }, - {IR_LONG, 208, 0, "CB2_I2" }, - {IR_LONG, 210, 0, "CB2_I3" }, - {IR_LONG, 212, 0, "CB2_L1KW" }, - {IR_LONG, 214, 0, "CB2_L2KW" }, - {IR_LONG, 216, 0, "CB2_L3KW" }, - {IR_LONG, 218, 0, "CB2_L1KVar" }, - {IR_LONG, 220, 0, "CB2_L2KVar" }, - {IR_LONG, 222, 0, "CB2_L3KVar" }, - {IR_LONG, 224, 0, "CB2_L1KVA" }, - {IR_LONG, 226, 0, "CB2_L2KVA" }, - {IR_LONG, 228, 0, "CB2_L3KVA" }, - {IR_LONG, 230, 0, "CB2_L1PF" }, - {IR_LONG, 232, 0, "CB2_L2PF" }, - {IR_LONG, 234, 0, "CB2_L3PF" }, - {IR_LONG, 236, 0, "CB2_V1THD" }, - {IR_LONG, 238, 0, "CB2_V2THD" }, - {IR_LONG, 240, 0, "CB2_V3THD" }, - {IR_LONG, 242, 0, "CB2_I1THD" }, - {IR_LONG, 244, 0, "CB2_I2THD" }, - {IR_LONG, 246, 0, "CB2_I3THD" }, - {IR_LONG, 248, 0, "CB2_I1Kfactor" }, - {IR_LONG, 250, 0, "CB2_I2Kfactor" }, - {IR_LONG, 252, 0, "CB2_I3Kfactor" }, - {IR_LONG, 254, 0, "CB2_I1TDD" }, - {IR_LONG, 256, 0, "CB2_I2TDD" }, - {IR_LONG, 258, 0, "CB2_I3TDD" }, - {IR_LONG, 260, 0, "CB2_V12" }, - {IR_LONG, 262, 0, "CB2_V23" }, - {IR_LONG, 264, 0, "CB2_V31" }, - {IR_LONG, 266, 0, "CB2_TotalKW" }, - {IR_LONG, 268, 0, "CB2_TotalKVar" }, - {IR_LONG, 270, 0, "CB2_TotalKVA" }, - {IR_LONG, 272, 0, "CB2_TotalPF" }, - {IR_LONG, 274, 0, "CB2_TotalPFLag" }, - {IR_LONG, 276, 0, "CB2_TotalPFLead" }, - {IR_LONG, 278, 0, "CB2_TotalKWImport" }, - {IR_LONG, 280, 0, "CB2_TotalKWExport" }, - {IR_LONG, 282, 0, "CB2_TotalKVarImport" }, - {IR_LONG, 284, 0, "CB2_TotalKVarExport" }, - {IR_LONG, 286, 0, "CB2_LN_Avg" }, - {IR_LONG, 288, 0, "CB2_LL_Avg" }, - {IR_LONG, 299, 0, "CB2_Status" }, + // Circuit Breaker 3 (CB1) + {IR_LONG, 306, 0, "CB3_I1" }, //0.01x + {IR_LONG, 308, 0, "CB3_I2" }, //0.01x + {IR_LONG, 310, 0, "CB3_I3" }, //0.01x + {IR_LONG, 370, 0, "CB3_kVA" }, //0.001x + {IR_LONG, 324, 0, "CB3_kVA1" }, //0.001x + {IR_LONG, 326, 0, "CB3_kVA2" }, //0.001x + {IR_LONG, 328, 0, "CB3_kVA3" }, //0.001x + {IR_LONG, 368, 0, "CB3_kVAR" }, //0.001x + {IR_LONG, 366, 0, "CB3_kW" }, //0.001x + {IR_LONG, 312, 0, "CB3_kW1" }, //0.001x + {IR_LONG, 314, 0, "CB3_kW2" }, //0.001x + {IR_LONG, 316, 0, "CB3_kW3" }, //0.001x + {IR_LONG, 1223, 0, "CB3_kWh" }, + {IR_LONG, 372, 0, "CB3_PF" }, //0.001x - // Circuit Breaker 3 (OB03) - {IR_LONG, 300, 0, "CB3_V1N" }, - {IR_LONG, 302, 0, "CB3_V2N" }, - {IR_LONG, 304, 0, "CB3_V3N" }, - {IR_LONG, 306, 0, "CB3_I1" }, - {IR_LONG, 308, 0, "CB3_I2" }, - {IR_LONG, 310, 0, "CB3_I3" }, - {IR_LONG, 312, 0, "CB3_L1KW" }, - {IR_LONG, 314, 0, "CB3_L2KW" }, - {IR_LONG, 316, 0, "CB3_L3KW" }, - {IR_LONG, 318, 0, "CB3_L1KVar" }, - {IR_LONG, 320, 0, "CB3_L2KVar" }, - {IR_LONG, 322, 0, "CB3_L3KVar" }, - {IR_LONG, 324, 0, "CB3_L1KVA" }, - {IR_LONG, 326, 0, "CB3_L2KVA" }, - {IR_LONG, 328, 0, "CB3_L3KVA" }, - {IR_LONG, 330, 0, "CB3_L1PF" }, - {IR_LONG, 332, 0, "CB3_L2PF" }, - {IR_LONG, 334, 0, "CB3_L3PF" }, - {IR_LONG, 336, 0, "CB3_V1THD" }, - {IR_LONG, 338, 0, "CB3_V2THD" }, - {IR_LONG, 340, 0, "CB3_V3THD" }, - {IR_LONG, 342, 0, "CB3_I1THD" }, - {IR_LONG, 344, 0, "CB3_I2THD" }, - {IR_LONG, 346, 0, "CB3_I3THD" }, - {IR_LONG, 348, 0, "CB3_I1Kfactor" }, - {IR_LONG, 350, 0, "CB3_I2Kfactor" }, - {IR_LONG, 352, 0, "CB3_I3Kfactor" }, - {IR_LONG, 354, 0, "CB3_I1TDD" }, - {IR_LONG, 356, 0, "CB3_I2TDD" }, - {IR_LONG, 358, 0, "CB3_I3TDD" }, - {IR_LONG, 360, 0, "CB3_V12" }, - {IR_LONG, 362, 0, "CB3_V23" }, - {IR_LONG, 364, 0, "CB3_V31" }, - {IR_LONG, 366, 0, "CB3_TotalKW" }, - {IR_LONG, 368, 0, "CB3_TotalKVar" }, - {IR_LONG, 370, 0, "CB3_TotalKVA" }, - {IR_LONG, 372, 0, "CB3_TotalPF" }, - {IR_LONG, 374, 0, "CB3_TotalPFLag" }, - {IR_LONG, 376, 0, "CB3_TotalPFLead" }, - {IR_LONG, 378, 0, "CB3_TotalKWImport" }, - {IR_LONG, 380, 0, "CB3_TotalKWExport" }, - {IR_LONG, 382, 0, "CB3_TotalKVarImport" }, - {IR_LONG, 384, 0, "CB3_TotalKVarExport" }, - {IR_LONG, 386, 0, "CB3_LN_Avg" }, - {IR_LONG, 388, 0, "CB3_LL_Avg" }, - {IR_LONG, 399, 0, "CB3_Status" }, + // Circuit Breaker 4 (CB1) + {IR_LONG, 406, 0, "CB4_I1" }, //0.01x + {IR_LONG, 408, 0, "CB4_I2" }, //0.01x + {IR_LONG, 410, 0, "CB4_I3" }, //0.01x + {IR_LONG, 470, 0, "CB4_kVA" }, //0.001x + {IR_LONG, 424, 0, "CB4_kVA1" }, //0.001x + {IR_LONG, 426, 0, "CB4_kVA2" }, //0.001x + {IR_LONG, 428, 0, "CB4_kVA3" }, //0.001x + {IR_LONG, 468, 0, "CB4_kVAR" }, //0.001x + {IR_LONG, 466, 0, "CB4_kW" }, //0.001x + {IR_LONG, 412, 0, "CB4_kW1" }, //0.001x + {IR_LONG, 414, 0, "CB4_kW2" }, //0.001x + {IR_LONG, 416, 0, "CB4_kW3" }, //0.001x + {IR_LONG, 1278, 0, "CB4_kWh" }, + {IR_LONG, 472, 0, "CB4_PF" }, //0.001x - // Circuit Breaker 4 (OB04) - {IR_LONG, 400, 0, "CB4_V1N" }, - {IR_LONG, 402, 0, "CB4_V2N" }, - {IR_LONG, 404, 0, "CB4_V3N" }, - {IR_LONG, 406, 0, "CB4_I1" }, - {IR_LONG, 408, 0, "CB4_I2" }, - {IR_LONG, 410, 0, "CB4_I3" }, - {IR_LONG, 412, 0, "CB4_L1KW" }, - {IR_LONG, 414, 0, "CB4_L2KW" }, - {IR_LONG, 416, 0, "CB4_L3KW" }, - {IR_LONG, 418, 0, "CB4_L1KVar" }, - {IR_LONG, 420, 0, "CB4_L2KVar" }, - {IR_LONG, 422, 0, "CB4_L3KVar" }, - {IR_LONG, 424, 0, "CB4_L1KVA" }, - {IR_LONG, 426, 0, "CB4_L2KVA" }, - {IR_LONG, 428, 0, "CB4_L3KVA" }, - {IR_LONG, 430, 0, "CB4_L1PF" }, - {IR_LONG, 432, 0, "CB4_L2PF" }, - {IR_LONG, 434, 0, "CB4_L3PF" }, - {IR_LONG, 436, 0, "CB4_V1THD" }, - {IR_LONG, 438, 0, "CB4_V2THD" }, - {IR_LONG, 440, 0, "CB4_V3THD" }, - {IR_LONG, 442, 0, "CB4_I1THD" }, - {IR_LONG, 444, 0, "CB4_I2THD" }, - {IR_LONG, 446, 0, "CB4_I3THD" }, - {IR_LONG, 448, 0, "CB4_I1Kfactor" }, - {IR_LONG, 450, 0, "CB4_I2Kfactor" }, - {IR_LONG, 452, 0, "CB4_I3Kfactor" }, - {IR_LONG, 454, 0, "CB4_I1TDD" }, - {IR_LONG, 456, 0, "CB4_I2TDD" }, - {IR_LONG, 458, 0, "CB4_I3TDD" }, - {IR_LONG, 460, 0, "CB4_V12" }, - {IR_LONG, 462, 0, "CB4_V23" }, - {IR_LONG, 464, 0, "CB4_V31" }, - {IR_LONG, 466, 0, "CB4_TotalKW" }, - {IR_LONG, 468, 0, "CB4_TotalKVar" }, - {IR_LONG, 470, 0, "CB4_TotalKVA" }, - {IR_LONG, 472, 0, "CB4_TotalPF" }, - {IR_LONG, 474, 0, "CB4_TotalPFLag" }, - {IR_LONG, 476, 0, "CB4_TotalPFLead" }, - {IR_LONG, 478, 0, "CB4_TotalKWImport" }, - {IR_LONG, 480, 0, "CB4_TotalKWExport" }, - {IR_LONG, 482, 0, "CB4_TotalKVarImport" }, - {IR_LONG, 484, 0, "CB4_TotalKVarExport" }, - {IR_LONG, 486, 0, "CB4_LN_Avg" }, - {IR_LONG, 488, 0, "CB4_LL_Avg" }, - {IR_LONG, 499, 0, "CB4_Status" }, + // Circuit Breaker 5 (CB1) + {IR_LONG, 506, 0, "CB5_I1" }, //0.01x + {IR_LONG, 508, 0, "CB5_I2" }, //0.01x + {IR_LONG, 510, 0, "CB5_I3" }, //0.01x + {IR_LONG, 570, 0, "CB5_kVA" }, //0.001x + {IR_LONG, 524, 0, "CB5_kVA1" }, //0.001x + {IR_LONG, 526, 0, "CB5_kVA2" }, //0.001x + {IR_LONG, 528, 0, "CB5_kVA3" }, //0.001x + {IR_LONG, 568, 0, "CB5_kVAR" }, //0.001x + {IR_LONG, 566, 0, "CB5_kW" }, //0.001x + {IR_LONG, 512, 0, "CB5_kW1" }, //0.001x + {IR_LONG, 514, 0, "CB5_kW2" }, //0.001x + {IR_LONG, 516, 0, "CB5_kW3" }, //0.001x + {IR_LONG, 1333, 0, "CB5_kWh" }, + {IR_LONG, 572, 0, "CB5_PF" }, //0.001x - // Circuit Breaker 5 (OB05) - {IR_LONG, 500, 0, "CB5_V1N" }, - {IR_LONG, 502, 0, "CB5_V2N" }, - {IR_LONG, 504, 0, "CB5_V3N" }, - {IR_LONG, 506, 0, "CB5_I1" }, - {IR_LONG, 508, 0, "CB5_I2" }, - {IR_LONG, 510, 0, "CB5_I3" }, - {IR_LONG, 512, 0, "CB5_L1KW" }, - {IR_LONG, 514, 0, "CB5_L2KW" }, - {IR_LONG, 516, 0, "CB5_L3KW" }, - {IR_LONG, 518, 0, "CB5_L1KVar" }, - {IR_LONG, 520, 0, "CB5_L2KVar" }, - {IR_LONG, 522, 0, "CB5_L3KVar" }, - {IR_LONG, 524, 0, "CB5_L1KVA" }, - {IR_LONG, 526, 0, "CB5_L2KVA" }, - {IR_LONG, 528, 0, "CB5_L3KVA" }, - {IR_LONG, 530, 0, "CB5_L1PF" }, - {IR_LONG, 532, 0, "CB5_L2PF" }, - {IR_LONG, 534, 0, "CB5_L3PF" }, - {IR_LONG, 536, 0, "CB5_V1THD" }, - {IR_LONG, 538, 0, "CB5_V2THD" }, - {IR_LONG, 540, 0, "CB5_V3THD" }, - {IR_LONG, 542, 0, "CB5_I1THD" }, - {IR_LONG, 544, 0, "CB5_I2THD" }, - {IR_LONG, 546, 0, "CB5_I3THD" }, - {IR_LONG, 548, 0, "CB5_I1Kfactor" }, - {IR_LONG, 550, 0, "CB5_I2Kfactor" }, - {IR_LONG, 552, 0, "CB5_I3Kfactor" }, - {IR_LONG, 554, 0, "CB5_I1TDD" }, - {IR_LONG, 556, 0, "CB5_I2TDD" }, - {IR_LONG, 558, 0, "CB5_I3TDD" }, - {IR_LONG, 560, 0, "CB5_V12" }, - {IR_LONG, 562, 0, "CB5_V23" }, - {IR_LONG, 564, 0, "CB5_V31" }, - {IR_LONG, 566, 0, "CB5_TotalKW" }, - {IR_LONG, 568, 0, "CB5_TotalKVar" }, - {IR_LONG, 570, 0, "CB5_TotalKVA" }, - {IR_LONG, 572, 0, "CB5_TotalPF" }, - {IR_LONG, 574, 0, "CB5_TotalPFLag" }, - {IR_LONG, 576, 0, "CB5_TotalPFLead" }, - {IR_LONG, 578, 0, "CB5_TotalKWImport" }, - {IR_LONG, 580, 0, "CB5_TotalKWExport" }, - {IR_LONG, 582, 0, "CB5_TotalKVarImport" }, - {IR_LONG, 584, 0, "CB5_TotalKVarExport" }, - {IR_LONG, 586, 0, "CB5_LN_Avg" }, - {IR_LONG, 588, 0, "CB5_LL_Avg" }, - {IR_LONG, 599, 0, "CB5_Status" }, - - // Circuit Breaker 6 (OB06) - {IR_LONG, 600, 0, "CB6_V1N" }, - {IR_LONG, 602, 0, "CB6_V2N" }, - {IR_LONG, 604, 0, "CB6_V3N" }, - {IR_LONG, 606, 0, "CB6_I1" }, - {IR_LONG, 608, 0, "CB6_I2" }, - {IR_LONG, 610, 0, "CB6_I3" }, - {IR_LONG, 612, 0, "CB6_L1KW" }, - {IR_LONG, 614, 0, "CB6_L2KW" }, - {IR_LONG, 616, 0, "CB6_L3KW" }, - {IR_LONG, 618, 0, "CB6_L1KVar" }, - {IR_LONG, 620, 0, "CB6_L2KVar" }, - {IR_LONG, 622, 0, "CB6_L3KVar" }, - {IR_LONG, 624, 0, "CB6_L1KVA" }, - {IR_LONG, 626, 0, "CB6_L2KVA" }, - {IR_LONG, 628, 0, "CB6_L3KVA" }, - {IR_LONG, 630, 0, "CB6_L1PF" }, - {IR_LONG, 632, 0, "CB6_L2PF" }, - {IR_LONG, 634, 0, "CB6_L3PF" }, - {IR_LONG, 636, 0, "CB6_V1THD" }, - {IR_LONG, 638, 0, "CB6_V2THD" }, - {IR_LONG, 640, 0, "CB6_V3THD" }, - {IR_LONG, 642, 0, "CB6_I1THD" }, - {IR_LONG, 644, 0, "CB6_I2THD" }, - {IR_LONG, 646, 0, "CB6_I3THD" }, - {IR_LONG, 648, 0, "CB6_I1Kfactor" }, - {IR_LONG, 650, 0, "CB6_I2Kfactor" }, - {IR_LONG, 652, 0, "CB6_I3Kfactor" }, - {IR_LONG, 654, 0, "CB6_I1TDD" }, - {IR_LONG, 656, 0, "CB6_I2TDD" }, - {IR_LONG, 658, 0, "CB6_I3TDD" }, - {IR_LONG, 660, 0, "CB6_V12" }, - {IR_LONG, 662, 0, "CB6_V23" }, - {IR_LONG, 664, 0, "CB6_V31" }, - {IR_LONG, 666, 0, "CB6_TotalKW" }, - {IR_LONG, 668, 0, "CB6_TotalKVar" }, - {IR_LONG, 670, 0, "CB6_TotalKVA" }, - {IR_LONG, 672, 0, "CB6_TotalPF" }, - {IR_LONG, 674, 0, "CB6_TotalPFLag" }, - {IR_LONG, 676, 0, "CB6_TotalPFLead" }, - {IR_LONG, 678, 0, "CB6_TotalKWImport" }, - {IR_LONG, 680, 0, "CB6_TotalKWExport" }, - {IR_LONG, 682, 0, "CB6_TotalKVarImport" }, - {IR_LONG, 684, 0, "CB6_TotalKVarExport" }, - {IR_LONG, 686, 0, "CB6_LN_Avg" }, - {IR_LONG, 688, 0, "CB6_LL_Avg" }, - {IR_LONG, 699, 0, "CB6_Status" }, - - // Circuit Breaker 7 (OB07) - {IR_LONG, 700, 0, "CB7_V1N" }, - {IR_LONG, 702, 0, "CB7_V2N" }, - {IR_LONG, 704, 0, "CB7_V3N" }, - {IR_LONG, 706, 0, "CB7_I1" }, - {IR_LONG, 708, 0, "CB7_I2" }, - {IR_LONG, 710, 0, "CB7_I3" }, - {IR_LONG, 712, 0, "CB7_L1KW" }, - {IR_LONG, 714, 0, "CB7_L2KW" }, - {IR_LONG, 716, 0, "CB7_L3KW" }, - {IR_LONG, 718, 0, "CB7_L1KVar" }, - {IR_LONG, 720, 0, "CB7_L2KVar" }, - {IR_LONG, 722, 0, "CB7_L3KVar" }, - {IR_LONG, 724, 0, "CB7_L1KVA" }, - {IR_LONG, 726, 0, "CB7_L2KVA" }, - {IR_LONG, 728, 0, "CB7_L3KVA" }, - {IR_LONG, 730, 0, "CB7_L1PF" }, - {IR_LONG, 732, 0, "CB7_L2PF" }, - {IR_LONG, 734, 0, "CB7_L3PF" }, - {IR_LONG, 736, 0, "CB7_V1THD" }, - {IR_LONG, 738, 0, "CB7_V2THD" }, - {IR_LONG, 740, 0, "CB7_V3THD" }, - {IR_LONG, 742, 0, "CB7_I1THD" }, - {IR_LONG, 744, 0, "CB7_I2THD" }, - {IR_LONG, 746, 0, "CB7_I3THD" }, - {IR_LONG, 748, 0, "CB7_I1Kfactor" }, - {IR_LONG, 750, 0, "CB7_I2Kfactor" }, - {IR_LONG, 752, 0, "CB7_I3Kfactor" }, - {IR_LONG, 754, 0, "CB7_I1TDD" }, - {IR_LONG, 756, 0, "CB7_I2TDD" }, - {IR_LONG, 758, 0, "CB7_I3TDD" }, - {IR_LONG, 760, 0, "CB7_V12" }, - {IR_LONG, 762, 0, "CB7_V23" }, - {IR_LONG, 764, 0, "CB7_V31" }, - {IR_LONG, 766, 0, "CB7_TotalKW" }, - {IR_LONG, 768, 0, "CB7_TotalKVar" }, - {IR_LONG, 770, 0, "CB7_TotalKVA" }, - {IR_LONG, 772, 0, "CB7_TotalPF" }, - {IR_LONG, 774, 0, "CB7_TotalPFLag" }, - {IR_LONG, 776, 0, "CB7_TotalPFLead" }, - {IR_LONG, 778, 0, "CB7_TotalKWImport" }, - {IR_LONG, 780, 0, "CB7_TotalKWExport" }, - {IR_LONG, 782, 0, "CB7_TotalKVarImport" }, - {IR_LONG, 784, 0, "CB7_TotalKVarExport" }, - {IR_LONG, 786, 0, "CB7_LN_Avg" }, - {IR_LONG, 788, 0, "CB7_LL_Avg" }, - {IR_LONG, 799, 0, "CB7_Status" }, - - // Circuit Breaker 8 (OB08) - {IR_LONG, 800, 0, "CB8_V1N" }, - {IR_LONG, 802, 0, "CB8_V2N" }, - {IR_LONG, 804, 0, "CB8_V3N" }, - {IR_LONG, 806, 0, "CB8_I1" }, - {IR_LONG, 808, 0, "CB8_I2" }, - {IR_LONG, 810, 0, "CB8_I3" }, - {IR_LONG, 812, 0, "CB8_L1KW" }, - {IR_LONG, 814, 0, "CB8_L2KW" }, - {IR_LONG, 816, 0, "CB8_L3KW" }, - {IR_LONG, 818, 0, "CB8_L1KVar" }, - {IR_LONG, 820, 0, "CB8_L2KVar" }, - {IR_LONG, 822, 0, "CB8_L3KVar" }, - {IR_LONG, 824, 0, "CB8_L1KVA" }, - {IR_LONG, 826, 0, "CB8_L2KVA" }, - {IR_LONG, 828, 0, "CB8_L3KVA" }, - {IR_LONG, 830, 0, "CB8_L1PF" }, - {IR_LONG, 832, 0, "CB8_L2PF" }, - {IR_LONG, 834, 0, "CB8_L3PF" }, - {IR_LONG, 836, 0, "CB8_V1THD" }, - {IR_LONG, 838, 0, "CB8_V2THD" }, - {IR_LONG, 840, 0, "CB8_V3THD" }, - {IR_LONG, 842, 0, "CB8_I1THD" }, - {IR_LONG, 844, 0, "CB8_I2THD" }, - {IR_LONG, 846, 0, "CB8_I3THD" }, - {IR_LONG, 848, 0, "CB8_I1Kfactor" }, - {IR_LONG, 850, 0, "CB8_I2Kfactor" }, - {IR_LONG, 852, 0, "CB8_I3Kfactor" }, - {IR_LONG, 854, 0, "CB8_I1TDD" }, - {IR_LONG, 856, 0, "CB8_I2TDD" }, - {IR_LONG, 858, 0, "CB8_I3TDD" }, - {IR_LONG, 860, 0, "CB8_V12" }, - {IR_LONG, 862, 0, "CB8_V23" }, - {IR_LONG, 864, 0, "CB8_V31" }, - {IR_LONG, 866, 0, "CB8_TotalKW" }, - {IR_LONG, 868, 0, "CB8_TotalKVar" }, - {IR_LONG, 870, 0, "CB8_TotalKVA" }, - {IR_LONG, 872, 0, "CB8_TotalPF" }, - {IR_LONG, 874, 0, "CB8_TotalPFLag" }, - {IR_LONG, 876, 0, "CB8_TotalPFLead" }, - {IR_LONG, 878, 0, "CB8_TotalKWImport" }, - {IR_LONG, 880, 0, "CB8_TotalKWExport" }, - {IR_LONG, 882, 0, "CB8_TotalKVarImport" }, - {IR_LONG, 884, 0, "CB8_TotalKVarExport" }, - {IR_LONG, 886, 0, "CB8_LN_Avg" }, - {IR_LONG, 888, 0, "CB8_LL_Avg" }, - {IR_LONG, 899, 0, "CB8_Status" }, - - // Circuit Breaker 8 (OB08) - {IR_LONG, 900, 0, "CB9_V1N" }, - {IR_LONG, 902, 0, "CB9_V2N" }, - {IR_LONG, 904, 0, "CB9_V3N" }, - {IR_LONG, 906, 0, "CB9_I1" }, - {IR_LONG, 908, 0, "CB9_I2" }, - {IR_LONG, 910, 0, "CB9_I3" }, - {IR_LONG, 912, 0, "CB9_L1KW" }, - {IR_LONG, 914, 0, "CB9_L2KW" }, - {IR_LONG, 916, 0, "CB9_L3KW" }, - {IR_LONG, 918, 0, "CB9_L1KVar" }, - {IR_LONG, 920, 0, "CB9_L2KVar" }, - {IR_LONG, 922, 0, "CB9_L3KVar" }, - {IR_LONG, 924, 0, "CB9_L1KVA" }, - {IR_LONG, 926, 0, "CB9_L2KVA" }, - {IR_LONG, 928, 0, "CB9_L3KVA" }, - {IR_LONG, 930, 0, "CB9_L1PF" }, - {IR_LONG, 932, 0, "CB9_L2PF" }, - {IR_LONG, 934, 0, "CB9_L3PF" }, - {IR_LONG, 936, 0, "CB9_V1THD" }, - {IR_LONG, 938, 0, "CB9_V2THD" }, - {IR_LONG, 940, 0, "CB9_V3THD" }, - {IR_LONG, 942, 0, "CB9_I1THD" }, - {IR_LONG, 944, 0, "CB9_I2THD" }, - {IR_LONG, 946, 0, "CB9_I3THD" }, - {IR_LONG, 948, 0, "CB9_I1Kfactor" }, - {IR_LONG, 950, 0, "CB9_I2Kfactor" }, - {IR_LONG, 952, 0, "CB9_I3Kfactor" }, - {IR_LONG, 954, 0, "CB9_I1TDD" }, - {IR_LONG, 956, 0, "CB9_I2TDD" }, - {IR_LONG, 958, 0, "CB9_I3TDD" }, - {IR_LONG, 960, 0, "CB9_V12" }, - {IR_LONG, 962, 0, "CB9_V23" }, - {IR_LONG, 964, 0, "CB9_V31" }, - {IR_LONG, 966, 0, "CB9_TotalKW" }, - {IR_LONG, 968, 0, "CB9_TotalKVar" }, - {IR_LONG, 970, 0, "CB9_TotalKVA" }, - {IR_LONG, 972, 0, "CB9_TotalPF" }, - {IR_LONG, 974, 0, "CB9_TotalPFLag" }, - {IR_LONG, 976, 0, "CB9_TotalPFLead" }, - {IR_LONG, 978, 0, "CB9_TotalKWImport" }, - {IR_LONG, 980, 0, "CB9_TotalKWExport" }, - {IR_LONG, 982, 0, "CB9_TotalKVarImport" }, - {IR_LONG, 984, 0, "CB9_TotalKVarExport" }, - {IR_LONG, 986, 0, "CB9_LN_Avg" }, - {IR_LONG, 988, 0, "CB9_LL_Avg" }, - {IR_LONG, 999, 0, "CB9_Status" }, - - {IR_FLOAT, 1068, 0, "Amps G" }, - {IR_FLOAT, 1066, 0, "Amps N" }, - {IR_FLOAT, 1087, 0, "kWh" }, - {IR_FLOAT, 1091, 0, "PF" }, + // Circuit Breaker 6 (CB1) + {IR_LONG, 606, 0, "CB6_I1" }, //0.01x + {IR_LONG, 608, 0, "CB6_I2" }, //0.01x + {IR_LONG, 610, 0, "CB6_I3" }, //0.01x + {IR_LONG, 670, 0, "CB6_kVA" }, //0.001x + {IR_LONG, 624, 0, "CB6_kVA1" }, //0.001x + {IR_LONG, 626, 0, "CB6_kVA2" }, //0.001x + {IR_LONG, 628, 0, "CB6_kVA3" }, //0.001x + {IR_LONG, 668, 0, "CB6_kVAR" }, //0.001x + {IR_LONG, 666, 0, "CB6_kW" }, //0.001x + {IR_LONG, 612, 0, "CB6_kW1" }, //0.001x + {IR_LONG, 614, 0, "CB6_kW2" }, //0.001x + {IR_LONG, 616, 0, "CB6_kW3" }, //0.001x + {IR_LONG, 1388, 0, "CB6_kWh" }, + {IR_LONG, 672, 0, "CB6_PF" }, //0.001x + // Circuit Breaker 7 (CB1) + {IR_LONG, 706, 0, "CB7_I1" }, //0.01x + {IR_LONG, 708, 0, "CB7_I2" }, //0.01x + {IR_LONG, 710, 0, "CB7_I3" }, //0.01x + {IR_LONG, 770, 0, "CB7_kVA" }, //0.001x + {IR_LONG, 724, 0, "CB7_kVA1" }, //0.001x + {IR_LONG, 726, 0, "CB7_kVA2" }, //0.001x + {IR_LONG, 728, 0, "CB7_kVA3" }, //0.001x + {IR_LONG, 768, 0, "CB7_kVAR" }, //0.001x + {IR_LONG, 766, 0, "CB7_kW" }, //0.001x + {IR_LONG, 712, 0, "CB7_kW1" }, //0.001x + {IR_LONG, 714, 0, "CB7_kW2" }, //0.001x + {IR_LONG, 716, 0, "CB7_kW3" }, //0.001x + {IR_LONG, 1443, 0, "CB7_kWh" }, + {IR_LONG, 772, 0, "CB7_PF" }, //0.001x + + // Circuit Breaker 8 (CB1) + {IR_LONG, 806, 0, "CB8_I1" }, //0.01x + {IR_LONG, 808, 0, "CB8_I2" }, //0.01x + {IR_LONG, 810, 0, "CB8_I3" }, //0.01x + {IR_LONG, 870, 0, "CB8_kVA" }, //0.001x + {IR_LONG, 824, 0, "CB8_kVA1" }, //0.001x + {IR_LONG, 826, 0, "CB8_kVA2" }, //0.001x + {IR_LONG, 828, 0, "CB8_kVA3" }, //0.001x + {IR_LONG, 868, 0, "CB8_kVAR" }, //0.001x + {IR_LONG, 866, 0, "CB8_kW" }, //0.001x + {IR_LONG, 812, 0, "CB8_kW1" }, //0.001x + {IR_LONG, 814, 0, "CB8_kW2" }, //0.001x + {IR_LONG, 816, 0, "CB8_kW3" }, //0.001x + {IR_LONG, 1498, 0, "CB8_kWh" }, + {IR_LONG, 872, 0, "CB8_PF" }, //0.001x + + // PDU Output + {IR_LONG, 906, 0, "Output_I1" }, //0.01x + {IR_LONG, 908, 0, "Output_I2" }, + {IR_LONG, 910, 0, "Output_I3" }, + {IR_LONG, 1068, 0, "Output_IG" }, + {IR_LONG, 1066, 0, "Output_IN" }, + {IR_LONG, 924, 0, "Output_kVA1" }, //0.001 + {IR_LONG, 926, 0, "Output_kVA2" }, + {IR_LONG, 928, 0, "Output_kVA3" }, + {IR_LONG, 968, 0, "Output_kVAR" }, //0.001 + {IR_LONG, 912, 0, "Output_kW1" }, //0.001x + {IR_LONG, 914, 0, "Output_kW2" }, + {IR_LONG, 916, 0, "Output_kW3" }, + {IR_LONG, 1086, 0, "Output_kWh" }, + {IR_LONG, 1091, 0, "Output_PF" }, //0.001 + {IR_LONG, 960, 0, "Output_V_AB" }, + {IR_LONG, 900, 0, "Output_V_AN" }, //0.01x + {IR_LONG, 962, 0, "Output_V_BC" }, + {IR_LONG, 902, 0, "Output_V_BN" }, + {IR_LONG, 964, 0, "Output_V_CA" }, + {IR_LONG, 904, 0, "Output_V_CN" }, + {IR, 1550, 0, "CB_Status" }, {IR, 1551, 0, "CB_Tripped" }, - }; //Size of modbus map used in FOR cycles, automatically calculated. From d94e4c3f4b1bff092bfb7215cf751b8e88a66840 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 27 Oct 2025 12:56:36 -0700 Subject: [PATCH 04/51] Added PHX3 EG CRAH --- platformio.ini | 13 +- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/README.md | 58 +++++++ .../StateUtils.cpp | 99 +++++++++++ .../StateUtils.h | 43 +++++ .../State_Fail.cpp | 99 +++++++++++ .../State_Running.cpp | 120 +++++++++++++ .../State_Standby.cpp | 117 +++++++++++++ .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 162 ++++++++++++++++++ .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/main.cpp | 86 ++++++++++ 9 files changed, 794 insertions(+), 3 deletions(-) create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/README.md create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h create mode 100644 src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index 259c977..0fe8268 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,10 +11,10 @@ [platformio] -default_envs = PHX3_VFD_ABB_ACH580_RTU ; Select here the name of the configuration you want to download +default_envs = PHX3_CRAH_LIEBERT_80_SLAB_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM50 +upload_port = COM9 [common_env_options] framework = arduino @@ -205,4 +205,11 @@ build_src_filter = -<*> + platform = espressif32 board = dfrobot_firebeetle2_esp32e extends = common_env_options -build_src_filter = -<*> + \ No newline at end of file +build_src_filter = -<*> + + +[env:PHX3_CRAH_LIEBERT_80_SLAB_TCP] +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/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/README.md b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/README.md new file mode 100644 index 0000000..db837dc --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/README.md @@ -0,0 +1,58 @@ +# CRAH Liebert 80 125 SLAB TCP + +## Brief Introduction +This version of the LIEBERT 80 SLAB Electrical Gallery CRAH has different registers from the existing +"CRAH_LIEBERT_80_125_SLAB_TCP" code, hence a new instance was created. The logic in this code is also +unique from the existing LIEBERT_80_125 CRAH unit. +This implementation assumes that on/off control and supply, return air temp setpoints are sent to CRAH unit +from Ignition- there is not an associated PLC program. + +## List of Equipment +This configuration has been used for these models: +* **PHX3 Liebert CW084DC1A1SDM7 SLAB**: 10-27-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 +On/Off Control by Coil 25 +Supply Air Temp Setpoint used for PID control of Fluid Control Valves 1&2 +Return Air Temp Setpoint used for PID control of Fan Speed +Unsure of difference between Fluid Control Valves 1 & 2, for this simulation they are assumed to operate the same +We have reached out to vendor for clarification of these two valves. + +### Standby State +* **Unit Status**: set to 2 (standby) +* **Free Cool Status**: set to 1 whenever in Standby Mode - Assuming whenever in Standby Mode will operate in Free Cooling mode +* **Fan Speed**: ramp to 0 +* **Return Humidity**: saw 0 to 80, increments of 5 +* **Return Air Temp**: single value 80 +/- 1 +* **Supply Air Temp**: single value 80 +/- 1 +* **Supply Air Flow**: ramp to 0 +* **Fluid Control Valve Position 1**: ramp to 0 +* **Fluid Control Valve Position 2**: ramp to 0 + +### Running State +* **Unit Status, Supply Fan Status, Cooling Status**: set to 1 +* **Return Humidity**: saw 0 to 80, increments of 5 (same as Standby Mode) +* **Return Air Temp**: saw 62 to 110, increments of 2 +* **Supply Air Temp**: saw 64 to 86, increments of 1 +* **Supply Air Flow**: saw 7 to 10, increments of 1 +* **Fan Speed**: PID control (Return Air Temp Setpoint, Return Air Temp) +* **Fluid Control Valve Position 1**: PID control (Supply Air Temp Setpoint, Supply Air Temp) +* **Fluid Control Valve Position 2**: PID control (Supply Air Temp Setpoint, Supply Air Temp) + +### Fail State +* **Unit Status**: set to 0 (off) +* **Free Cool Status**: set to 0 +* **Fan Speed**: ramp to 0 +* **Return Humidity**: saw 0 to 80, increments of 5 +* **Return Air Temp**: single value 80 +/- 1 +* **Supply Air Temp**: single value 80 +/- 1 +* **Supply Air Flow**: ramp to 0 +* **Fluid Control Valve Position 1**: ramp to 0 +* **Fluid Control Valve Position 2**: ramp to 0 \ No newline at end of file diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp new file mode 100644 index 0000000..b50dc7f --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -0,0 +1,99 @@ +/** + * @file StateUtils.cpp + * @brief Implementation of the StateUtils class. + * @author Robert J. Davis + * @date 2025-10-24 + * + * This file contains implementation of utility functions that are used in multiple States. + */ +#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 "ModbusPoints/Modbus_Point.h" +#include "ModbusPoints/Modbus_FloatDecorator.h" +#include "Equipment/Equipment.h" +#include "States/State_Standby.h" +#include "States/State_Running.h" +#include "States/State_Fail.h" +#include "States/State.h" +#include "StateUtils.h" +#include +#include +#if defined(USE_MODBUS_IP) + #include +#else + #include +#endif + +/** + * @brief This function will update the Alarm status DI bits according to the Alarm Commands from Coils (Modscan) + * It will also update the Common Alarm: if any alarm is active, the Common alarm will also be active. + * + * This is a function used in the update() of the Standby, Running, and Fail States. + * +*/ + +void updateAlarms(Equipment* equipment){ + const std::vector alarmDescriptions = { + "Alarm Fan Overload", "Alarm Loss of Air", "Alarm Compressor 1A Overload", "Alarm Compressor 2A Overload", + "Alarm Smoke Detected", "Alarm Water Detected", "Alarm Standby Unit On", "Alarm CP High Water", + "Alarm Room Sensor Failure", "Alarm Power Loss", "Alarm High Return Air Temp", "Alarm Low Return Air Temp", + "Alarm High Return Humidity", "Alarm Low Return Humidity", "Alarm Clogged Filter", "Alarm Supply Sensor Failure", + "Alarm Unit Network Failure", "Alarm High Supply Temp", "Alarm Low Supply Temp", "Alarm Compressor 1 Short Cycle", + "Alarm Compressor 2 Short Cycle", "Alarm Fan Failure", "Alarm Circuit 1 Low Pressure", "Alarm Circuit 2 Low Pressure", + "Alarm Circuit 1 High Pressure", "Alarm Circuit 2 High Pressure", "Alarm High Return Air Dew Point", + "Alarm Low Return Air Dew Point", "Alarm Compressor 1 Over Temp", "Alarm Compressor 2 Over Temp", + "Common Alarm", "Alarm Pump Failure", "Alarm Comm Loss Condenser 1", "Alarm Comm Loss Condenser 2", + "Alarm Compressor 1B Overload", "Alarm Compressor 2B Overload" + }; + + const std::vector alarmCommands = { + "Alarm Fan Overload ON", "Alarm Loss of Air ON", "Alarm Compressor 1A Overload ON", "Alarm Compressor 2A Overload ON", + "Alarm Smoke Detected ON", "Alarm Water Detected ON", "Alarm Standby Unit On ON", "Alarm High Water ON", + "Alarm Room Sensor Failure ON", "Alarm Power Loss ON", "Alarm High Return Air Temp ON", "Alarm Low Return Air Temp ON", + "Alarm High Return Humidity ON", "Alarm Low Return Humidity ON", "Alarm Clogged Filter ON", "Alarm Supply Sensor Failure ON", + "Alarm Unit Network Failure ON", "Alarm High Supply Temp ON", "Alarm Low Supply Temp ON", "Alarm Compressor 1 Short Cycle ON", + "Alarm Compressor 2 Short Cycle ON", "Alarm Fan Failure ON", "Alarm Circuit 1 Low Pressure ON", "Alarm Circuit 2 Low Pressure ON", + "Alarm Circuit 1 High Pressure ON", "Alarm Circuit 2 High Pressure ON", "Alarm High Return Air Dew Point ON", + "Alarm Low Return Air Dew Point ON", "Alarm Compressor 1 Over Temp ON", "Alarm Compressor 2 Over Temp ON", + "Common Alarm ON", "Alarm Pump Failure ON", "Alarm Comm Loss Condenser 1 ON", "Alarm Comm Loss Condenser 2 ON", + "Alarm Compressor 1B Overload ON", "Alarm Compressor 2B Overload ON" + }; + + int numAlarms = 0; + for (int i =0; i< alarmCommands.size() && i < alarmDescriptions.size(); ++i) { + Modbus_Point* commandPoint = equipment->getModbus_Point(alarmCommands[i]); + Modbus_Point* alarmPoint = equipment->getModbus_Point(alarmDescriptions[i]); + if (commandPoint) { + alarmPoint->setValue(commandPoint->getValue()); + if (alarmPoint->getValue() == 1) numAlarms++; + } + } + if (numAlarms >= 1) equipment->setModbus_Point("Common Alarm", 1); + else equipment->setModbus_Point("Common Alarm", 0); +} + +/** + * @brief Updates Dehumidifier Mode + * + * This function will update the Dehumidifier Mode based on Dehumidifier Mode Command (Coil 1) + * received from Modscan. This is for simulation purposes only - in practice, the Chiller + * will transition to Dehumidifier mode based on its own internal logic. + * + * For ease of testing, this is a function used in the update() of the Standby, Running, and Fail States. + * +*/ + +void updateDehumidifier(Equipment* equipment){ + Modbus_Point* DehumidifierCommand = equipment->getModbus_Point("Dehumidifier Mode ON"); + Modbus_Point* DehumidifierStatus = equipment->getModbus_Point("Dehumidifier Status"); + if (DehumidifierCommand->getValue() == 1) { + DehumidifierStatus->setValue(1); + } + else { + DehumidifierStatus->setValue(0); + } +} \ No newline at end of file diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h new file mode 100644 index 0000000..e2c1196 --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h @@ -0,0 +1,43 @@ +/** + * @file config.h + * @brief StateUtils class + * @author Robert J Davis + * @date 2025-10-24 + * + * Defines the StateUtils class, which contains utility functions used in multiple States. + */ + +#pragma once + +#include "ModbusPoints/Modbus_Point.h" +#include "ModbusPoints/Modbus_FloatDecorator.h" +#include "Equipment/Equipment.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 + +template +class State; + +/** + * @brief Checks common alarms (non-fail alarms) and updates the Common Alarm Modbus point. + * @param equipment Pointer to the Equipment instance. + * @return void + */ +void updateAlarms(Equipment* equipment); + +/** + * @brief Checks Dehumidifier Mode ON from Modscan (Coil 1) and updates the Dehumidifier Status point. + * @param equipment Pointer to the Equipment instance. + * @return void + */ +void updateDehumidifier(Equipment* equipment); \ No newline at end of file diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp new file mode 100644 index 0000000..888d1b4 --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp @@ -0,0 +1,99 @@ +/** + * @file State_Fail.cpp + * @brief Implementation of the FailState class. + * @author Robert J Davis + * @date 2025-10-24 + * + * 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_Saw.h" +#include "Strategies/Strategy_PID.h" +#include "States/State_Standby.h" +#include "States/State_Running.h" +#include "States/State_Fail.h" +#include "StateUtils.h" +#if defined(USE_MODBUS_IP) + #include +#else + #include +#endif + +/** + * @brief Constructs a new FailState object with a list of active alarms. + * + * This constructor ramps Fan Speed, Supply Air Flow, and Fluid Control Valves to 0. + * Return Humidity continues to saw between 0-80 (for sake of Ignition display verification) + * Return and Supply Air Temp is 80 +/- 1 + * + */ +template<> +FailState::FailState(const std::vector& activeAlarms) { + addStrategy("Fan Speed", new RampStrategy(0.0f, 10.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 5.0f, 1000)); + addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 1000)); + addStrategy("Fluid Control Valve Position 1", new RampStrategy(0.0f, 5.0f, 1000)); + addStrategy("Fluid Control Valve Position 2", new RampStrategy(0.0f, 5.0f, 1000)); +} + +/** + * @brief Executes the fail state's logic for one update cycle. + * + * My programming logic: ensure System On/Off Control is always set to 0. This will ensure + * that after the fault is cleared, the unit will enter StandbyMode and will then be commanded + * by Operator to starts, rather than automatically restarting. This is my assumption for the sake + * of testing, actual implementation may be different. + * + * The only way to exit FailState is for the Smoke Detect and High Water alarms to be cleared. + * Upon exiting FailState, the unit will enter StandbyState. + * + * @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"); + + setPointValue(equipment, "System On/Off Control", 0); // my programming logic: when clear fault, should be sent to Standby Mode + updateAlarms(equipment); + updateDehumidifier(equipment); // Dehumidifier mode can be toggled while in FailState (for ease of Ignition HMI verification) + + bool smokeDetectState = getPointValue(equipment, "Alarm Smoke Detected"); + bool highWaterState = getPointValue(equipment, "Alarm CP High Water"); + if (smokeDetectState == false && highWaterState == false){ + return new StandbyState(); + } + + _applyStrategies(equipment); + return nullptr; +} + +/** + * @brief Logic to execute once when entering the fail state. + * Sets the Unit Status, Supply Fan Status, Cooling Status, and Free Cooling Status to 0 (off). + * @param equipment Pointer to the Equipment instance. + */ +template<> +void FailState::enterState(Equipment* equipment) { + setPointValue(equipment, "Unit Status", 0); + setPointValue(equipment, "Supply Fan Status", 0); + setPointValue(equipment, "Cooling Status", 0); + setPointValue(equipment, "Free Cooling Status", 0); +} + +/** + * @brief Logic to execute once when exiting the fail 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/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp new file mode 100644 index 0000000..d0ce726 --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp @@ -0,0 +1,120 @@ +/** + * @file State_Running.cpp + * @brief Implementation of the RunningState class. + * @author Robert J Davis + * @date 2025-10-24 + * + * 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 "StateUtils.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. + * Return Air Temp saws between 66 and 110 to cover both low alarm and high alarm states (72 and 100). + * Supply Air Temp saws between 68 and 86 to cover both low alarm and high alarm states (72 and 78). + * Supply Air Flow saws between 7 to 10 (for Ignition HMI verification, no correlation to expected values). + * Fan Speed adjusts via PID on Return Air Temp Setpoint (note: PID parameters are set in base code, can't be adjusted) + * Fluid Control Valve Positions adjust via PID on Supply Air Temp Setpoint. + * Unsure of the difference between FCV 1 and 2, therefore they just match for the sake of testing. + * + */ +template<> +RunningState::RunningState() { + addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 5.0f, 1000)); + addStrategy("Return Air Temp", new SawStrategy(66.0f, 110.0f, 2.0f, 1000)); + addStrategy("Supply Air Temp", new SawStrategy(68.0f, 86.0f, 1.0f, 1000)); + addStrategy("Supply Air Flow", new SawStrategy(7.0f, 10.0f, 1.0f, 1000)); + addStrategy("Fan Speed", new PIDStrategy("Return Air Temp Setpoint", 1000, "Return Air Temp")); + addStrategy("Fluid Control Valve Position 1", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); + addStrategy("Fluid Control Valve Position 2", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); +} + +/** + * @brief Executes the running state's logic for one update cycle. + * + * This method first checks for state transition commands: + * 1. Updates Alarm states + * 2. Updates Dehumidifier mode (for ease of Ignition verification) + * If the Smoke Detected or High Water alarms annunciate, send to FailState. + * + * 3. Check if On/Off Command = 0, then send to Standby State. + * + * 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) { + Serial.println("Running update function"); + + updateAlarms(equipment); + updateDehumidifier(equipment); + + bool smokeDetect = getPointValue(equipment, "Alarm Smoke Detected"); + bool highWater = getPointValue(equipment, "Alarm CP High Water"); + std::vector activeFailAlarms; + if (smokeDetect) activeFailAlarms.push_back("Alarm Smoke Detected"); + if (highWater) activeFailAlarms.push_back("Alarm CP High Water"); + if (!activeFailAlarms.empty()){ + return new FailState(activeFailAlarms); + } + + int On_Off_Command = getPointValue(equipment, "System On/Off Control"); + if (On_Off_Command == 0){ + return new StandbyState(); + } + + // Apply any strategies defined for the standby state + _applyStrategies(equipment); + return nullptr; +} + +/** + * @brief Logic to execute once when entering the running state. + * Sets the Unit Status, Supply Fan Status, Cooling Status, and Free Cooling Status 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 + setPointValue(equipment, "Unit Status", 1); + setPointValue(equipment, "Supply Fan Status", 1); + setPointValue(equipment, "Cooling Status", 1); + setPointValue(equipment, "Free Cooling Status", 0); +} + +/** + * @brief Logic to execute once when exiting the running state. + * All State transitions are executed on enterState function, therefore + * this exitState function is not used. + * @param equipment Pointer to the Equipment instance. + */ +template<> +void RunningState::exitState(Equipment* equipment) { + // Cleanup logic to run when the equipment leaves this state +} \ No newline at end of file diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp new file mode 100644 index 0000000..5db3e93 --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp @@ -0,0 +1,117 @@ +/** + * @file State_Standby.cpp + * @brief Implementation of the StandbyState class. + * @author Robert J Davis + * @date 2025-10-24 + * + * 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 "StateUtils.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 ramps Fan Speed, Supply Air Flow, and Fluid Control Valves to 0. + * Return Humidity continues to saw between 0-80 (for sake of Ignition display verification) + * Return and Supply Air Temp is 80 +/- 1. + */ +template<> +StandbyState::StandbyState() { + addStrategy("Fan Speed", new RampStrategy(0.0f, 10.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 5.0f, 1000)); + addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 1000)); + addStrategy("Fluid Control Valve Position 1", new RampStrategy(0.0f, 5.0f, 1000)); + addStrategy("Fluid Control Valve Position 2", new RampStrategy(0.0f, 5.0f, 1000)); +} + +/** + * @brief Executes the standby state's logic for one update cycle. + * + * This method first checks for state transition commands: + * 1. Updates Alarm states + * 2. Updates Dehumidifier mode (for ease of Ignition verification) + * If the Smoke Detected or High Water alarms annunciate, send to FailState. + * + * 3. Check if On/Off Command = 1, then send to Running State. + * + * If no transition occurs, it applies the strategies defined for the standby state. + * + * @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"); + + updateAlarms(equipment); + updateDehumidifier(equipment); + + bool smokeDetect = getPointValue(equipment, "Alarm Smoke Detected"); + bool highWater = getPointValue(equipment, "Alarm CP High Water"); + std::vector activeFailAlarms; + if (smokeDetect == true) activeFailAlarms.push_back("Alarm Smoke Detected"); + if (highWater == true) activeFailAlarms.push_back("Alarm CP High Water"); + if (!activeFailAlarms.empty()){ + return new FailState(activeFailAlarms); + } + + int On_Off_Command = getPointValue(equipment, "System On/Off Control"); + if (On_Off_Command == 1){ + return new RunningState(); + } + + // Apply any strategies defined for the standby state + _applyStrategies(equipment); + return nullptr; +} + +/** + * @brief Logic to execute once when entering the standby state. + * Sets the Unit Status = 2 (standby) and Free Cooling Status to 1 (assume whenever in Standby Mode, runs in Free Cooling) + * Supply Fan Status, Cooling Status, Dehumidifier Status, and On/Off Command set to 0. + * @param equipment Pointer to the Equipment instance. + */ +template<> +void StandbyState::enterState(Equipment* equipment) { + // Set all Unit Status to 2 (standby), ensure On Off Command also set to 0. + setPointValue(equipment, "Unit Status", 2); + setPointValue(equipment, "Supply Fan Status", 0); + setPointValue(equipment, "Cooling Status", 0); + setPointValue(equipment, "Free Cooling Status", 1); + setPointValue(equipment, "Dehumidifier Status", 0); + setPointValue(equipment, "System OnOff Control", 0); +} + +/** + * @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/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h new file mode 100644 index 0000000..f1040fb --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -0,0 +1,162 @@ +/** + * @file config.h + * @brief Main configuration file for the Electrical Gallery CRAH Unit (TCP) emulator - Vertiv Liebert 80 Slab TCP PHX3 DC1 + * @author Robert J Davis + * @date 2025-10-24 + * + * 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 = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ + const char *password = "52761492"; /**< @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[] = +{ + {COIL, 0, 0, "Dehumidifier Mode ON"}, // For Arduino testing only + {COIL, 1, 0, "Alarm Smoke Detected ON"}, // For Arduino testing only - will send to FailState + {COIL, 2, 0, "Alarm High Water ON"}, // For Arduino testing only - will send to FailState + + {COIL, 3, 0, "Alarm Fan Overload ON"}, // For Arduino testing only + {COIL, 4, 0, "Alarm Loss of Air ON"}, // For Arduino testing only + {COIL, 5, 0, "Alarm Compressor 1A Overload ON"}, // For Arduino testing only + {COIL, 6, 0, "Alarm Compressor 2A Overload ON"}, // For Arduino testing only + {COIL, 7, 0, "Alarm Water Detected ON"}, // For Arduino testing only + {COIL, 8, 0, "Alarm Standby Unit On ON"}, // For Arduino testing only + {COIL, 9, 0, "Alarm Room Sensor Failure ON"}, // For Arduino testing only + {COIL, 10, 0, "Alarm Power Loss ON"}, // For Arduino testing only + {COIL, 11, 0, "Alarm Clogged Filter ON"}, // For Arduino testing only + {COIL, 12, 0, "Alarm Supply Sensor Failure ON"}, // For Arduino testing only + {COIL, 13, 0, "Alarm Unit Network Failure ON"}, // For Arduino testing only + {COIL, 14, 0, "Alarm Compressor 1 Short Cycle ON"}, // For Arduino testing only + {COIL, 15, 0, "Alarm Compressor 2 Short Cycle ON"}, // For Arduino testing only + {COIL, 16, 0, "Alarm Fan Failure ON"}, // For Arduino testing only + + {COIL, 17, 0, "Alarm Circuit 1 Low Pressure ON"}, // For Arduino testing only + {COIL, 18, 0, "Alarm Circuit 2 Low Pressure ON"}, // For Arduino testing only + {COIL, 19, 0, "Alarm Circuit 1 High Pressure ON"}, // For Arduino testing only + {COIL, 20, 0, "Alarm Circuit 2 High Pressure ON"}, // For Arduino testing only + {COIL, 21, 0, "Alarm High Return Air Dew Point ON"}, // For Arduino testing only + {COIL, 22, 0, "Alarm Low Return Air Dew Point ON"}, // For Arduino testing only + {COIL, 23, 0, "Common Alarm ON"}, // For Arduino testing only + {COIL, 24, 0, "System On/Off Control"}, + {COIL, 25, 0, "Alarm Compressor 1 Over Temp ON"}, // For Arduino testing only + {COIL, 26, 0, "Alarm Compressor 2 Over Temp ON"}, // For Arduino testing only + {COIL, 27, 0, "Alarm Pump Failure ON"}, // For Arduino testing only + {COIL, 28, 0, "Alarm Comm Loss Condenser 1 ON"}, // For Arduino testing only + {COIL, 29, 0, "Alarm Comm Loss Condenser 2 ON"}, // For Arduino testing only + {COIL, 30, 0, "Alarm Compressor 1B Overload ON"}, // For Arduino testing only + {COIL, 31, 0, "Alarm Compressor 2B Overload ON"}, // For Arduino testing only + + {DI, 24, 0, "Supply Fan Status"}, + {DI, 25, 0, "Cooling Status"}, + {DI, 26, 0, "Free Cooling Status"}, + {DI, 30, 0, "Dehumidifier Status"}, + + {DI, 33, 0, "Alarm Fan Overload"}, + {DI, 34, 0, "Alarm Loss of Air"}, + {DI, 38, 0, "Alarm Compressor 1A Overload"}, + {DI, 42, 0, "Alarm Compressor 2A Overload"}, + {DI, 46, 0, "Alarm Smoke Detected"}, + {DI, 47, 0, "Alarm Water Detected"}, + {DI, 50, 0, "Alarm Standby Unit On"}, + {DI, 51, 0, "Alarm CP High Water"}, + {DI, 52, 0, "Alarm Room Sensor Failure"}, + {DI, 60, 0, "Alarm Power Loss"}, + {DI, 66, 0, "Alarm High Return Air Temp"}, // 100 set in Ignition + {DI, 67, 0, "Alarm Low Return Air Temp"}, // 72 set in Ignition + {DI, 68, 0, "Alarm High Return Humidity"}, // 60 set in Ignition + {DI, 69, 0, "Alarm Low Return Humidity"}, // 20 set in Ignition + {DI, 75, 0, "Alarm Clogged Filter"}, + {DI, 76, 0, "Alarm Supply Sensor Failure"}, + {DI, 91, 0, "Alarm Unit Network Failure"}, + {DI, 208, 0, "Alarm High Supply Temp"}, // 78 set in Ignition + {DI, 209, 0, "Alarm Low Supply Temp"}, // 72 set in Ignition + {DI, 211, 0, "Alarm Compressor 1 Short Cycle"}, + {DI, 212, 0, "Alarm Compressor 2 Short Cycle"}, + {DI, 217, 0, "Alarm Fan Failure"}, + {DI, 239, 0, "Alarm Circuit 1 Low Pressure"}, + {DI, 240, 0, "Alarm Circuit 2 Low Pressure"}, + {DI, 241, 0, "Alarm Circuit 1 High Pressure"}, + {DI, 242, 0, "Alarm Circuit 2 High Pressure"}, + {DI, 344, 0, "Alarm High Return Air Dew Point"}, + {DI, 345, 0, "Alarm Low Return Air Dew Point"}, + {DI, 348, 0, "Alarm Compressor 1 Over Temp"}, + {DI, 349, 0, "Alarm Compressor 2 Over Temp"}, + {DI, 350, 0, "Common Alarm"}, + {DI, 491, 0, "Alarm Pump Failure"}, + {DI, 682, 0, "Alarm Comm Loss Condenser 1"}, + {DI, 683, 0, "Alarm Comm Loss Condenser 2"}, + {DI, 740, 0, "Alarm Compressor 1B Overload"}, + {DI, 741, 0, "Alarm Compressor 2B Overload"}, + + {IR, 99, 0, "Unit Status"}, // 0:off, 1:on, 2:standby + {IR, 102, 0, "Fan Speed"}, + {IR, 129, 0, "Return Humidity"}, + {IR, 742, 0, "Return Air Temp"}, + {IR, 743, 0, "Supply Air Temp"}, + {IR, 1465, 0, "Supply Air Flow"}, + {IR, 2050, 0, "Fluid Control Valve Position 1"}, + {IR, 2051, 0, "Fluid Control Valve Position 2"}, + + {HR, 732, 73, "Supply Air Temp Setpoint"}, + {HR, 753, 80, "Return Air Temp Setpoint"}, +}; +//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/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/main.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/main.cpp @@ -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 +#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); + } +} From 900f38fb5c0832db1579b221a3ce1704af708a10 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Mon, 27 Oct 2025 17:46:42 -0500 Subject: [PATCH 05/51] save --- platformio.ini | 3 +- .../ATS/ATS_Eaton_ATC900_RPD_TCP/config.h | 2 +- .../Breaker/BKR_ABB_XT_TCP/State_Running.cpp | 34 +- .../Breaker/BKR_ABB_XT_TCP/State_Standby.cpp | 14 +- src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h | 6 +- .../BKR_Eaton_PXR20_25/State_Running.cpp | 6 +- .../BKR_Eaton_PXR20_25/State_Standby.cpp | 9 +- src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h | 8 +- .../PDU_Maverick_Power_TCP/State_Running.cpp | 443 ++++++++++-------- .../PDU_Maverick_Power_TCP/State_Standby.cpp | 10 + src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h | 6 +- src/EPMS/PQM/PQM_PM9000_TCP/State_Running.cpp | 2 +- src/EPMS/PQM/PQM_PM9000_TCP/State_Standby.cpp | 1 + src/EPMS/PQM/PQM_PM9000_TCP/config.h | 4 +- .../UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp | 184 ++++---- .../UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp | 117 ++--- .../UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp | 103 ++-- src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h | 6 +- 18 files changed, 527 insertions(+), 431 deletions(-) diff --git a/platformio.ini b/platformio.ini index 8d5873a..06422a6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,5 +1,4 @@ ; PlatformIO Project Configuration File -; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages @@ -11,7 +10,7 @@ [platformio] -default_envs = ATS_Eaton_ATC900_RPD_TCP ; Select here the name of the configuration you want to download +default_envs = BKR_ABB_XT_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM50 diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h index 65b58f6..b781b9e 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 169); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 33, 172); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp index 4aaabcd..54fbf46 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp @@ -38,11 +38,11 @@ */ 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("Volts AB", new SingleValueStrategy(4800.0F, 5.0f, 1000)); + addStrategy("Volts BC", new SingleValueStrategy(4800.0F, 5.0f, 1000)); + addStrategy("Volts CA", new SingleValueStrategy(4800.0F, 5.0f, 1000)); - addStrategy("PF", new SingleValueStrategy(90.0f, 1.0f, 1000)); + addStrategy("PF", new SingleValueStrategy(900.0f, 1.0f, 1000)); addStrategy("Amps A", new SingleValueStrategy(1.0f, 10.0f, 1000)); addStrategy("Amps B", new SingleValueStrategy(1.0f, 10.0f, 1000)); @@ -68,7 +68,10 @@ State* RunningState::update(Equipment* equipment) Serial.println("Running update function"); Serial.println("Running update function"); float State_Ctrl = getPointValue(equipment, "State Control"); - if (State_Ctrl == 1){ + if (State_Ctrl == 0){ + return new StandbyState(); + } + if (State_Ctrl == 2){ return new StandbyState(); } // Apply any strategies defined for the standby state @@ -76,9 +79,9 @@ State* RunningState::update(Equipment* equipment) 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); + setPointValue(equipment, "Volts AN", volts_AB/1.732f); + setPointValue(equipment, "Volts BN", volts_BC/1.732f); + setPointValue(equipment, "Volts CN", volts_AC/1.732f); int I_load = getPointValue(equipment, "Load"); @@ -86,18 +89,21 @@ State* RunningState::update(Equipment* equipment) float load = static_cast(I_load); float rating = static_cast(I_rating); float real_load = rating * (load/100.0f); - setPointValue(equipment, "Amps A", real_load); - setPointValue(equipment, "Amps B", real_load); - setPointValue(equipment, "Amps C", real_load); + setPointValue(equipment, "Amps A", real_load * 10.0f); + setPointValue(equipment, "Amps B", real_load * 10.0f); + setPointValue(equipment, "Amps C", real_load * 10.0f); + setPointValue(equipment, "Amps G", volts_AB * 0.037f); + setPointValue(equipment, "Amps N", volts_BC * 0.034f); float pf = getPointValue(equipment, "PF"); - float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/3.0f) * real_load * (pf/100))/100; - float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/3.0f) * real_load)/100; + float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load * (pf/100.0f))/100.0f; + float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load )/100.0f; setPointValue(equipment, "kW", kw); setPointValue(equipment, "kVA", kva); + setPointValue(equipment, "kWh", 1724.0f); // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -113,7 +119,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", 1); + setBitValue(equipment, "CB Position", 1, true); } /** diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp index c51a4c2..ab732df 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp @@ -57,9 +57,16 @@ 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){ + if (State_Ctrl == 1){ return new RunningState(); } + + if (State_Ctrl == 0){ + setBitValue(equipment, "CB Position", 12, false); + } + if (State_Ctrl == 2){ + setBitValue(equipment, "CB Position", 12, true); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -75,7 +82,7 @@ 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); + setBitValue(equipment, "CB Position", 0, false); setPointValue(equipment, "Volts AB", 0.0f); setPointValue(equipment, "Volts BC", 0.0f); setPointValue(equipment, "Volts CA", 0.0f); @@ -86,8 +93,11 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "Amps A", 0.0f); setPointValue(equipment, "Amps B", 0.0f); setPointValue(equipment, "Amps C", 0.0f); + setPointValue(equipment, "Amps G", 0.0f); + setPointValue(equipment, "Amps N", 0.0f); setPointValue(equipment, "kW", 0.0f); setPointValue(equipment, "kVA", 0.0f); + setPointValue(equipment, "kWh", 0.0f); } /** diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h b/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h index f3742ab..018a5ed 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h @@ -23,8 +23,8 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 30, 241); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 30, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 33, 150); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -63,7 +63,7 @@ modbusMap mb_map[] = {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 - {IR_LONG, 41, 0, "CB Position"}, + {IR_LONG, 41, 0, "CB Position"}, //b0 close open b12 tripped {IR_LONG, 101, 0, "Amps A"}, {IR_LONG, 103, 0, "Amps B"}, {IR_LONG, 105, 0, "Amps C"}, diff --git a/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp index 16d2903..431ab66 100644 --- a/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Running.cpp @@ -68,7 +68,10 @@ 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){ + if (State_Ctrl == 0){ + return new StandbyState(); + } + if (State_Ctrl == 2){ return new StandbyState(); } // Apply any strategies defined for the standby state @@ -118,6 +121,7 @@ void RunningState::enterState(Equipment* equipment) { Serial.println("Enter Running State..."); // You could also update a Modbus register to show the "standby" state setPointValue(equipment, "CB Position", 2048); + setPointValue(equipment, "CB Trip", 0.0f); } diff --git a/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp index 5dd2e42..f2195c2 100644 --- a/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/State_Standby.cpp @@ -57,9 +57,16 @@ 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){ + if (State_Ctrl == 1){ return new RunningState(); } + + if (State_Ctrl == 0){ + setPointValue(equipment, "CB Trip", 0.0f); + } + if (State_Ctrl == 2){ + setPointValue(equipment, "CB Trip", 1.0f); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h index 79be276..6a3bd12 100644 --- a/src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h +++ b/src/EPMS/Breaker/BKR_Eaton_PXR20_25/config.h @@ -21,10 +21,10 @@ * @{ */ #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. */ + const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 33, 167); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp index c3e5fca..765a521 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp @@ -40,68 +40,86 @@ std::string cbs[] = {"CB1", "CB2", "CB3", "CB4", "CB5", "CB6", "CB7", "CB8"}; template<> RunningState::RunningState() { + addStrategy("Input_I1", new SingleValueStrategy(40.0f, 30.0f, 1000)); + addStrategy("Input_I2", new SingleValueStrategy(40.0f, 30.0f, 1000)); + addStrategy("Input_I3", new SingleValueStrategy(40.0f, 30.0f, 1000)); + addStrategy("Input_kVA", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Input_kVAR", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Input_kW", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Input_kWh", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_PF", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Input_V_AB", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_V_AN", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_V_BC", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_V_BN", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_V_CA", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_V_CN", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_LL_Avg", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Input_LN_Avg", new SingleValueStrategy(3.0f, 2.0f, 1000)); + for (const std::string& cb : cbs) { std::string tag = ""; - tag = cb + "_V1N"; + tag = ""; + tag = cb + "_I1"; addStrategy(tag, new SingleValueStrategy(40.0f, 30.0f, 1000)); tag = ""; - tag = cb + "_V2N"; + tag = cb + "_I2"; addStrategy(tag, new SingleValueStrategy(40.0f, 30.0f, 1000)); tag = ""; - tag = cb + "_V3N"; + tag = cb + "_I3"; addStrategy(tag, new SingleValueStrategy(40.0f, 30.0f, 1000)); - tag = ""; - tag = cb + "_V1THD"; - addStrategy(tag, new SingleValueStrategy(20.0f, 7.0f, 1000)); + tag = cb + "_kVA"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_V2THD"; - addStrategy(tag, new SingleValueStrategy(20.0f, 7.0f, 1000)); + tag = cb + "_kVA1"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_V3THD"; - addStrategy(tag, new SingleValueStrategy(20.0f, 7.0f, 1000)); - tag = ""; - tag = cb + "_I1THD"; - addStrategy(tag, new SingleValueStrategy(100.0f, 12.0f, 1000)); + tag = cb + "_kVA2"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I2THD"; - addStrategy(tag, new SingleValueStrategy(100.0f, 12.0f, 1000)); + tag = cb + "_kVA3"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I3THD"; - addStrategy(tag, new SingleValueStrategy(100.0f, 12.0f, 1000)); + tag = cb + "_kVAR"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I1Kfactor"; - addStrategy(tag, new SingleValueStrategy(30.0f, 6.0f, 1000)); + tag = cb + "_kW"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I2Kfactor"; - addStrategy(tag, new SingleValueStrategy(30.0f, 6.0f, 1000)); + tag = cb + "_kW1"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I3Kfactor"; - addStrategy(tag, new SingleValueStrategy(30.0f, 6.0f, 1000)); + tag = cb + "_kW2"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I1TDD"; - addStrategy(tag, new SingleValueStrategy(50.0f, 9.0f, 1000)); + tag = cb + "_kW3"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); tag = ""; - tag = cb + "_I2TDD"; - addStrategy(tag, new SingleValueStrategy(50.0f, 9.0f, 1000)); + tag = cb + "_kWh"; + addStrategy(tag, new SingleValueStrategy(0.1f, 100.0f, 1000)); tag = ""; - tag = cb + "_I3TDD"; - addStrategy(tag, new SingleValueStrategy(50.0f, 9.0f, 1000)); - tag = ""; - tag = cb + "_V12"; - addStrategy(tag, new SingleValueStrategy(0.0f, 30.0f, 1000)); - tag = ""; - tag = cb + "_V23"; - addStrategy(tag, new SingleValueStrategy(0.0f, 30.0f, 1000)); - tag = ""; - tag = cb + "_V31"; - addStrategy(tag, new SingleValueStrategy(0.0f, 30.0f, 1000)); + tag = cb + "_PF"; + addStrategy(tag, new SingleValueStrategy(150.0f, 100.0f, 1000)); } - addStrategy("Amps G", new SingleValueStrategy(0.0f, 2.0f, 1000)); - addStrategy("Amps N", new SingleValueStrategy(0.0f, 3.0f, 1000)); - addStrategy("kWh", new RampStrategy(5000000.0f, 1.0f, 1000)); - addStrategy("PF", new SingleValueStrategy(0.0f, 1.0f, 1000)); + + addStrategy("Output_I1", new SingleValueStrategy(30.0f, 20.0f, 1000)); + addStrategy("Output_I2", new SingleValueStrategy(30.0f, 30.0f, 1000)); + addStrategy("Output_I3", new SingleValueStrategy(30.0f, 20.0f, 1000)); + addStrategy("Output_IG", new SingleValueStrategy(30.0f, 30.0f, 1000)); + addStrategy("Output_IN", new SingleValueStrategy(30.0f, 20.0f, 1000)); + addStrategy("Output_kVA1", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Output_kVA2", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Output_kVA3", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Output_kWh", new SingleValueStrategy(3.0f, 2.0f, 1000)); + addStrategy("Output_PF", new SingleValueStrategy(150.0f, 100.0f, 1000)); + addStrategy("Output_V_AB", new SingleValueStrategy(30.0f, 20.0f, 1000)); + addStrategy("Output_V_AN", new SingleValueStrategy(30.0f, 30.0f, 1000)); + addStrategy("Output_V_BC", new SingleValueStrategy(30.0f, 20.0f, 1000)); + addStrategy("Output_V_BN", new SingleValueStrategy(30.0f, 30.0f, 1000)); + addStrategy("Output_V_CA", new SingleValueStrategy(30.0f, 20.0f, 1000)); + addStrategy("Output_V_CN", new SingleValueStrategy(30.0f, 30.0f, 1000)); } /** @@ -132,14 +150,14 @@ State* RunningState::update(Equipment* equipment) float cb_count = 0.0f; for (const std::string& cb :cbs){ std::string tag = ""; - tag = "Px " + cb; - if (cb == "CB0") continue; + tag = "Px_" + cb; float cb_status = getPointValue(equipment, tag); if (cb_status == 1.0f){ cb_count += 1.0f; } } - int cb_num = 0; + Serial.printf("CB_ CLosed = %f \n", cb_count); + int cb_num = 1; for (const std::string& cb : cbs) { std::string tag = ""; Strategy_Behavior* strategy = nullptr; @@ -148,83 +166,75 @@ State* RunningState::update(Equipment* equipment) float cb_status = getPointValue(equipment, tag); float percent_load = getPointValue(equipment, "Px Load"); float Rating = getPointValue(equipment, "Px Rating"); - float total_load = Rating * (percent_load /100.0f); - float cb_load = total_load / cb_count; - + float cb_load = 400.0f * (percent_load /1000.0f); + if (cb_status == 1.0f){ setBitValue(equipment, "CB_Status", cb_num, true); setBitValue(equipment, "CB_Tripped", cb_num, false); - strategy = getStrategy("Amps G"); - static_cast(strategy)->setSetpoint(65.0f); - strategy = getStrategy("Amps N"); - static_cast(strategy)->setSetpoint(50.0f); - strategy = getStrategy("PF"); - static_cast(strategy)->setSetpoint(90.0f); - tag = ""; - tag = cb + "_V1N"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(2700.0f); - tag = ""; - tag = cb + "_V2N"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(2700.0f); - tag = ""; - tag = cb + "_V3N"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(2700.0f); - - tag = ""; - tag = cb + "_V12"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(4800.0f); - tag = ""; - tag = cb + "_V23"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(4800.0f); - tag = ""; - tag = cb + "_V31"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(4800.0f); - tag = ""; tag = cb + "_I1"; - setPointValue(equipment, tag, total_load * 100.0f); + setPointValue(equipment, tag, cb_load * 1000.0f); tag = ""; tag = cb + "_I2"; - setPointValue(equipment, tag, total_load * 100.0f); + setPointValue(equipment, tag, cb_load * 1000.0f); tag = ""; tag = cb + "_I3"; - setPointValue(equipment, tag, total_load * 100.0f); + setPointValue(equipment, tag, cb_load * 1000.0f); + tag = ""; + tag = cb + "_PF"; + setPointValue(equipment, tag, 910.0f); + tag = ""; + tag = cb + "_PF"; + float pf = getPointValue(equipment, tag); + tag = ""; - tag = cb + "_L1KW"; - setPointValue(equipment, tag, total_load * 1715.0f); + tag = cb + "_kW1"; + setPointValue(equipment, tag, cb_load * 48000.0f * pf); + float kW1 = getPointValue(equipment, tag); tag = ""; - tag = cb + "_L2KW"; - setPointValue(equipment, tag, total_load * 1715.0f); + tag = cb + "_kW2"; + setPointValue(equipment, tag, cb_load * 48000.0f * pf); + float kW2 = getPointValue(equipment, tag); tag = ""; - tag = cb + "_L3KW"; - setPointValue(equipment, tag, total_load * 1715.0f); + tag = cb + "_kW3"; + setPointValue(equipment, tag, cb_load * 48000.0f * pf); + float kW3 = getPointValue(equipment, tag); + tag = ""; + tag = cb + "_kW"; + setPointValue(equipment, tag, ((kW1 + kW2 + kW3) / 3.0f)*1000.0f); + tag = ""; + tag = cb + "_kWh"; + setPointValue(equipment, tag, 1325.0f); + tag = ""; + tag = cb + "_kVA"; + setPointValue(equipment, tag, cb_load * 480.0f * 10000.0f); + tag = ""; + tag = cb + "_kVA"; + setPointValue(equipment, tag, cb_load * 480.0f * 10000.0f); + tag = ""; + tag = cb + "_kVA"; + setPointValue(equipment, tag, cb_load * 480.0f * 10000.0f); tag = ""; - tag = cb + "_L1KVar"; - setPointValue(equipment, tag, total_load * 1715.0f * 0.9f); + tag = cb + "_kVA1"; + float kVA1 = getPointValue(equipment, tag); tag = ""; - tag = cb + "_L2KVar"; - setPointValue(equipment, tag, total_load * 1715.0f * 0.9f); + tag = cb + "_kVA2"; + float kVA2 = getPointValue(equipment, tag); tag = ""; - tag = cb + "_L3KVar"; - setPointValue(equipment, tag, total_load * 1715.0f * 0.9f); + tag = cb + "_kVA3"; + float kVA3 = getPointValue(equipment, tag); + float kVA = (kVA1 + kVA2 + kVA3) * 1732.0f; tag = ""; - tag = cb + "_L1KVA"; - setPointValue(equipment, tag, total_load * 1715.0f); + tag = cb + "_kVA"; + setPointValue(equipment, tag, kVA); tag = ""; - tag = cb + "_L2KVA"; - setPointValue(equipment, tag, total_load * 1715.0f); - tag = ""; - tag = cb + "_L3KVA"; - setPointValue(equipment, tag, total_load * 1715.0f); + tag = cb + "_kVAR"; + setPointValue(equipment, tag, kVA / pf); + + } else{ if (cb_status == 2.0f){ @@ -233,110 +243,147 @@ State* RunningState::update(Equipment* equipment) setBitValue(equipment, "CB_Tripped", cb_num, false); } setBitValue(equipment, "CB_Status", cb_num, false); - strategy = getStrategy("Amps G"); - static_cast(strategy)->setSetpoint(0.0f); - strategy = getStrategy("Amps N"); - static_cast(strategy)->setSetpoint(0.0f); - strategy = getStrategy("PF"); - static_cast(strategy)->setSetpoint(0.0f); - tag = ""; - tag = cb + "_V1N"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(0.0f); - tag = ""; - tag = cb + "_V2N"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(0.0f); - tag = ""; - tag = cb + "_V3N"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(0.0f); - - tag = ""; - tag = cb + "_V12"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(0.0f); - tag = ""; - tag = cb + "_V23"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(0.0f); - tag = ""; - tag = cb + "_V31"; - strategy = getStrategy(tag); - static_cast(strategy)->setSetpoint(0.0f); - - tag = ""; - tag = cb + "_I1"; - setPointValue(equipment, tag, total_load); - tag = ""; - tag = cb + "_I2"; - setPointValue(equipment, tag, total_load); - tag = ""; - tag = cb + "_I3"; - setPointValue(equipment, tag, total_load); - - tag = ""; - tag = cb + "_L1KW"; - setPointValue(equipment, tag, total_load*0.0f); - tag = ""; - tag = cb + "_L2KW"; - setPointValue(equipment, tag, total_load*0.0f); - tag = ""; - tag = cb + "_L3KW"; - setPointValue(equipment, tag, total_load*0.0f); - - tag = ""; - tag = cb + "_L1KVar"; - setPointValue(equipment, tag, total_load*0.0f); - tag = ""; - tag = cb + "_L2KVar"; - setPointValue(equipment, tag, total_load*0.0f); - tag = ""; - tag = cb + "_L3KVar"; - setPointValue(equipment, tag, total_load*0.0f); - tag = ""; - tag = cb + "_L1KVA"; - setPointValue(equipment, tag, 0.0f); - tag = ""; - tag = cb + "_L2KVA"; - setPointValue(equipment, tag, 0.0f); - tag = ""; - tag = cb + "_L3KVA"; - setPointValue(equipment, tag, 0.0f); + tag = ""; + tag = cb + "_I1"; + setPointValue(equipment, tag, 40.0f); + tag = ""; + tag = cb + "_I2"; + setPointValue(equipment, tag, 0.0f); + tag = ""; + tag = cb + "_I3"; + setPointValue(equipment, tag, 40.0f); + tag = ""; + tag = cb + "_kVA"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kVA1"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kVA2"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kVA3"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kVAR"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kW"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kW1"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kW2"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kW3"; + setPointValue(equipment, tag, 150.0f); + tag = ""; + tag = cb + "_kWh"; + setPointValue(equipment, tag, 0.5f); + tag = ""; + tag = cb + "_PF"; + setPointValue(equipment, tag, 150.0f); } cb_num++; - float kw1 = getPointValue(equipment, cb + "_L1KW"); - float kw2 = getPointValue(equipment, cb + "_L2KW"); - float kw3 = getPointValue(equipment, cb + "_L3KW"); - tag = ""; - tag = cb + "_TotalKW"; - setPointValue(equipment, tag, kw1 + kw2 + kw3); + + } + Serial.printf("CB_ CLosed = %f \n", cb_count); + if (cb_count > 0.0f){ + Serial.println("At least one breaker closed..."); + float percent_load = getPointValue(equipment, "Px Load"); + float cb_load = 400.0f * (percent_load /1000.0f); + setPointValue(equipment, "Input_I1", cb_count * cb_load *100.0f); + setPointValue(equipment, "Input_I2", cb_count * cb_load *100.0f); + setPointValue(equipment, "Input_I3", cb_count * cb_load *100.0f); + setPointValue(equipment, "Output_I1", cb_count * cb_load *100.0f); + setPointValue(equipment, "Output_I2", cb_count * cb_load*100.0f); + setPointValue(equipment, "Output_I3", cb_count * cb_load*100.0f); + setPointValue(equipment, "Output_IG", cb_count * 750.0f); + setPointValue(equipment, "Output_IN", cb_count * 482.0f); + + float pf = 0.92f; + setPointValue(equipment, "Input_PF", pf * 930.0f); + setPointValue(equipment, "Output_PF", pf); + float i1 = getPointValue(equipment, "Input_I1"); + float i2 = getPointValue(equipment, "Input_I2"); + float i3 = getPointValue(equipment, "Input_I3"); + + setPointValue(equipment, "Input_kW", 480.0f * ((i1 + i2 + i3) / 3.0f)); + float kW = getPointValue(equipment, "Input_kW"); + setPointValue(equipment, "Input_kVA", kW * 1.732f); + setPointValue(equipment, "Output_kVA1", (kW * 1.732f)/3.0f); + setPointValue(equipment, "Output_kVA2", (kW * 1.732f)/3.0f); + setPointValue(equipment, "Output_kVA3", (kW * 1.732f)/3.0f); + setPointValue(equipment, "Input_kVAR", kW * 1.732f* pf); + setPointValue(equipment, "Output_kVAR", kW * 1.732f* pf); - float kvar1 = getPointValue(equipment, cb + "_L1KVar"); - float kvar2 = getPointValue(equipment, cb + "_L2KVar"); - float kvar3 = getPointValue(equipment, cb + "_L3KVar"); - tag = ""; - tag = cb + "_TotalKVar"; - setPointValue(equipment, tag, kvar1 + kvar2 + kvar3); + setPointValue(equipment, "Output_kW1", kW /3.0f); + setPointValue(equipment, "Output_kW2", kW /3.0f); + setPointValue(equipment, "Output_kW3", kW /3.0f); + + setPointValue(equipment, "Output_kWh", 1423.0f); + + + setPointValue(equipment, "Input_V_AB", 4800.0f); + setPointValue(equipment, "Input_V_AN", 2700.0f); + setPointValue(equipment, "Input_V_BC", 4800.0f); + setPointValue(equipment, "Input_V_BN", 2700.0f); + setPointValue(equipment, "Input_V_CA", 4800.0f); + setPointValue(equipment, "Input_V_CN", 2700.0f); + setPointValue(equipment, "Input_LL_Avg", 4800.0f); + setPointValue(equipment, "Input_LN_Avg", 2700.0f); + setPointValue(equipment, "Output_V_AB", 4800.0f); + setPointValue(equipment, "Output_V_AN", 2700.0f); + setPointValue(equipment, "Output_V_BC", 4800.0f); + setPointValue(equipment, "Output_V_BN", 2700.0f); + setPointValue(equipment, "Output_V_CA", 4800.0f); + setPointValue(equipment, "Output_V_CN", 2700.0f); + } else { + Serial.println("No breaker closed..."); + setPointValue(equipment, "Input_I1", 50.0f); + setPointValue(equipment, "Input_I2", 50.0f); + setPointValue(equipment, "Input_I3", 50.0f); + setPointValue(equipment, "Output_I1", 50.0f); + setPointValue(equipment, "Output_I2", 50.0f); + setPointValue(equipment, "Output_I3", 50.0f); + setPointValue(equipment, "Output_IG", 50.0f); + setPointValue(equipment, "Output_IN", 50.0f); + setPointValue(equipment, "Input_PF", 0.0f); + setPointValue(equipment, "Output_PF", 0.0f); + setPointValue(equipment, "Input_kW", 0.0f); + setPointValue(equipment, "Input_kVA", 0.0f); + setPointValue(equipment, "Output_kVA1", 0.0f); + setPointValue(equipment, "Output_kVA2", 0.0f); + setPointValue(equipment, "Output_kVA3", 0.0f); + setPointValue(equipment, "Input_kVAR", 0.0f); + setPointValue(equipment, "Output_kVAR", 0.0f); + setPointValue(equipment, "Output_kW1", 0.0f); + setPointValue(equipment, "Output_kW2", 0.0f); + setPointValue(equipment, "Output_kW3", 0.0f); + setPointValue(equipment, "Output_kWh", 1.0f); + setPointValue(equipment, "Input_V_AB", 4800.0f); + setPointValue(equipment, "Input_V_AN", 2700.0f); + setPointValue(equipment, "Input_V_BC", 4800.0f); + setPointValue(equipment, "Input_V_BN", 2700.0f); + setPointValue(equipment, "Input_V_CA", 4800.0f); + setPointValue(equipment, "Input_V_CN", 2700.0f); + setPointValue(equipment, "Input_LL_Avg", 4800.0f); + setPointValue(equipment, "Input_LN_Avg", 2700.0f); + setPointValue(equipment, "Output_V_AB", 10.0f); + setPointValue(equipment, "Output_V_AN", 10.0f); + setPointValue(equipment, "Output_V_BC", 10.0f); + setPointValue(equipment, "Output_V_BN", 10.0f); + setPointValue(equipment, "Output_V_CA", 10.0f); + setPointValue(equipment, "Output_V_CN", 10.0f); - float kva1 = getPointValue(equipment, cb + "_L1KVA"); - float kva2 = getPointValue(equipment, cb + "_L2KVA"); - float kva3 = getPointValue(equipment, cb + "_L3KVA"); - tag = ""; - tag = cb + "_TotalKVA"; - setPointValue(equipment, tag, kvar1 + kva2 + kva3); - - float pf1 = getPointValue(equipment, cb + "_L1PF"); - float pf2 = getPointValue(equipment, cb + "_L2PF"); - float pf3 = getPointValue(equipment, cb + "_L3PF"); - float total_pf = (pf1 + pf2 + pf3) / 3.0f; - tag = ""; - tag = cb + "_TotalPF"; - setPointValue(equipment, tag, total_pf); } + + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Standby.cpp b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Standby.cpp index 369b295..b35142e 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Standby.cpp +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Standby.cpp @@ -79,6 +79,16 @@ template<> void StandbyState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Standby State..."); + setPointValue(equipment, "Input_V_AB", 0.0f); + setPointValue(equipment, "Input_V_AN", 0.0f); + setPointValue(equipment, "Input_V_BC", 0.0f); + setPointValue(equipment, "Input_V_BN", 0.0f); + setPointValue(equipment, "Input_V_CA", 0.0f); + setPointValue(equipment, "Input_V_CN", 0.0f); + setPointValue(equipment, "Input_LL_Avg", 0.0f); + setPointValue(equipment, "Input_LN_Avg", 0.0f); + setPointValue(equipment, "Output_PF", 0.0f); + } /** diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h index f601499..cd8b96f 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h @@ -22,8 +22,8 @@ */ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ - const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 178); /**< @brief The static IP address for the device. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 33, 181); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -46,8 +46,6 @@ ModbusRTU mb; #endif - - /** * @defgroup ModbusMapConfig Modbus Map Configuration * @brief Defines the Modbus register map and related parameters for the emulator. diff --git a/src/EPMS/PQM/PQM_PM9000_TCP/State_Running.cpp b/src/EPMS/PQM/PQM_PM9000_TCP/State_Running.cpp index e60e869..8e3480f 100644 --- a/src/EPMS/PQM/PQM_PM9000_TCP/State_Running.cpp +++ b/src/EPMS/PQM/PQM_PM9000_TCP/State_Running.cpp @@ -43,7 +43,7 @@ RunningState::RunningState() { addStrategy("Volts CA", new SingleValueStrategy(480.0F, 5.0f, 1000)); addStrategy("PF", new SingleValueStrategy(0.9f, 0.05f, 1000)); - + addStrategy("Frequency", new SingleValueStrategy(60.0f, 0.7f, 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)); diff --git a/src/EPMS/PQM/PQM_PM9000_TCP/State_Standby.cpp b/src/EPMS/PQM/PQM_PM9000_TCP/State_Standby.cpp index 0600853..65ab9ca 100644 --- a/src/EPMS/PQM/PQM_PM9000_TCP/State_Standby.cpp +++ b/src/EPMS/PQM/PQM_PM9000_TCP/State_Standby.cpp @@ -87,6 +87,7 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "Amps C", 0.0f); setPointValue(equipment, "kW", 0.0f); setPointValue(equipment, "kVA", 0.0f); + setPointValue(equipment, "Frequency", 0.0f); } /** diff --git a/src/EPMS/PQM/PQM_PM9000_TCP/config.h b/src/EPMS/PQM/PQM_PM9000_TCP/config.h index f323a0c..8886755 100644 --- a/src/EPMS/PQM/PQM_PM9000_TCP/config.h +++ b/src/EPMS/PQM/PQM_PM9000_TCP/config.h @@ -23,8 +23,8 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 30, 241); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 30, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 33, 174); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp index ce7c1a1..b3c7894 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Battery.cpp @@ -40,32 +40,32 @@ */ template<> BatteryState::BatteryState() { - addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS C-A", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); + addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS C-A", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output RMS Current Phase A", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output RMS Current Phase B", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output RMS Current Phase C", new RampStrategy(10.0f, 50.0f, 1000)); addStrategy("System Output Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); - addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0f, 5.0f, 1000)); - addStrategy("System Output Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Power Phase A", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Power Phase B", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Power Phase C", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs A", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs B", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs C", new RampStrategy(10.0f, 50.0f, 1000)); - addStrategy("Battery Time Remaining", new RampStrategy(0.0F, 0.3f, 1000)); - addStrategy("Percentage Load", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("Battery Time Remaining", new RampStrategy(0.0f, 3.0f, 1000)); + addStrategy("Percentage Load", new RampStrategy(0.0f, 5.0f, 1000)); } /** @@ -96,80 +96,88 @@ State* BatteryState::update(Equipment* equipment) case 4: return new BypassState(); break; - default: + default: break; - } - - float rating = getPointValue(equipment, "Px Rating"); - float load = getPointValue(equipment, "Px Load"); - float real_load = rating * (load/100.f); - - Strategy_Behavior* ramp_strat = nullptr; + } + + float Battery_time = getPointValue(equipment, "Battery Time Remaining"); + float Bat_Percent = Battery_time /4.80f; + float select = 1.0f; + if (Bat_Percent > 98.0f){ + setPointValue(equipment, "UPS Battery Status2", 0.0f); + select = 1.0f; + } + if (Bat_Percent > 20.0f) { + setPointValue(equipment, "UPS Battery Status1", 2.0f); + setPointValue(equipment, "Battery Low", 0.0f); + select = 1.0f; + } + if (Bat_Percent <= 20.0f && Bat_Percent >= 5.0f){ + setPointValue(equipment, "UPS Battery Status1", 3.0f); + setPointValue(equipment, "Battery Low", 1.0f); + select = 0.8f; + } + if (Bat_Percent < 5.0f){ + setPointValue(equipment, "UPS Battery Status1", 4.0f); + select = 0.05f; + } + float rating = getPointValue(equipment, "Px Rating"); + float load = getPointValue(equipment, "Px Load"); + float real_load = (rating) * (load/100.0f); + + Strategy_Behavior* ramp_strat = nullptr; //Output strategies - float Out_Vab = getPointValue(equipment, "System Output RMS A-B"); - ramp_strat = getStrategy("System Output RMS Current Phase A"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vab); - float Out_Vbc = getPointValue(equipment, "System Output RMS B-C"); - ramp_strat = getStrategy("System Output RMS Current Phase B"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vbc); - float Out_Vca = getPointValue(equipment, "System Output RMS C-A"); - ramp_strat = getStrategy("System Output RMS Current Phase C"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vca); + float Out_Vab = getPointValue(equipment, "System Output RMS A-B"); + ramp_strat = getStrategy("System Output RMS Current Phase A"); + static_cast(ramp_strat)->setTarget(real_load*select); + float Out_Vbc = getPointValue(equipment, "System Output RMS B-C"); + ramp_strat = getStrategy("System Output RMS Current Phase B"); + static_cast(ramp_strat)->setTarget(real_load*select); + float Out_Vca = getPointValue(equipment, "System Output RMS C-A"); + ramp_strat = getStrategy("System Output RMS Current Phase C"); + static_cast(ramp_strat)->setTarget(real_load*select); + + float Out_Van = getPointValue(equipment, "System Output RMS A-N"); + float Out_Ia = getPointValue(equipment, "System Output RMS Current Phase A"); + float Out_PFa = getPointValue(equipment, "System Output Power Factor Phs A"); + ramp_strat = getStrategy("System Output Power Phase A"); + static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia); + ramp_strat = getStrategy("System Output Apparent Power Phs A"); + static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * Out_PFa); + + float Out_Vbn = getPointValue(equipment, "System Output RMS B-N"); + float Out_Ib = getPointValue(equipment, "System Output RMS Current Phase B"); + float Out_PFb = getPointValue(equipment, "System Output Power Factor Phs B"); + ramp_strat = getStrategy("System Output Power Phase B"); + static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib); + ramp_strat = getStrategy("System Output Apparent Power Phs B"); + static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * Out_PFb); + + float Out_Vcn = getPointValue(equipment, "System Output RMS C-N"); + float Out_Ic = getPointValue(equipment, "System Output RMS Current Phase C"); + float Out_PFc = getPointValue(equipment, "System Output Power Factor Phs C"); + ramp_strat = getStrategy("System Output Power Phase C"); + static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic); + ramp_strat = getStrategy("System Output Apparent Power Phs C"); + static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * Out_PFc); - float Out_Van = getPointValue(equipment, "System Output RMS A-N"); - float Out_Ia = getPointValue(equipment, "System Output RMS Current Phase A"); - float Out_PFa = getPointValue(equipment, "System Output Power Factor Phs A"); - ramp_strat = getStrategy("System Output Power Phase A"); - static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia); - ramp_strat = getStrategy("System Output Apparent Power Phs A"); - static_cast(ramp_strat)->setTarget(Out_Van * Out_Ia * Out_PFa); - - float Out_Vbn = getPointValue(equipment, "System Output RMS B-N"); - float Out_Ib = getPointValue(equipment, "System Output RMS Current Phase B"); - float Out_PFb = getPointValue(equipment, "System Output Power Factor Phs B"); - ramp_strat = getStrategy("System Output Power Phase B"); - static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib); - ramp_strat = getStrategy("System Output Apparent Power Phs B"); - static_cast(ramp_strat)->setTarget(Out_Vbn * Out_Ib * Out_PFb); - - float Out_Vcn = getPointValue(equipment, "System Output RMS C-N"); - float Out_Ic = getPointValue(equipment, "System Output RMS Current Phase C"); - float Out_PFc = getPointValue(equipment, "System Output Power Factor Phs C"); - ramp_strat = getStrategy("System Output Power Phase C"); - static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic); - ramp_strat = getStrategy("System Output Apparent Power Phs C"); - static_cast(ramp_strat)->setTarget(Out_Vcn * Out_Ic * Out_PFc); - - float Battery_time = getPointValue(equipment, "Battery Time Remaining"); - float Bat_Percent = Battery_time /4.80f; - if (Bat_Percent > 98.0f){ - setPointValue(equipment, "UPS Battery Status2", 0.0f); - } - if (Bat_Percent > 20.0f) { - setPointValue(equipment, "UPS Battery Status1", 2.0f); - setPointValue(equipment, "Battery Low", 0.0f); - } - if (Bat_Percent <= 20.0f && Bat_Percent >= 5.0f){ - setPointValue(equipment, "UPS Battery Status1", 3.0f); - setPointValue(equipment, "Battery Low", 1.0f); - } - if (Bat_Percent < 5.0f){ - setPointValue(equipment, "UPS Battery Status1", 4.0f); - } + setPointValue(equipment, "System Output Power", (real_load * Out_Vab)/1000.0f); + setPointValue(equipment, "System Output Apparent Power", (real_load* Out_Vab * 0.9f)/1000.0f); + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; -} - -/** - * @brief Logic to execute once when entering the Battery 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 BatteryState::enterState(Equipment* equipment) { - // Logic to run when the equipment enters this state - Serial.println("Enter Battery State..."); + } + + /** + * @brief Logic to execute once when entering the Battery 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 BatteryState::enterState(Equipment* equipment) { + // Logic to run when the equipment enters this state + Serial.println("Enter Battery State..."); setPointValue(equipment, "System Input RMS A-B", 0.0f); setPointValue(equipment, "System Input RMS B-C", 0.0f); setPointValue(equipment, "System Input RMS C-A", 0.0f); diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp index 73a2b31..0c92458 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Bypass.cpp @@ -42,72 +42,72 @@ template<> BypassState::BypassState() { //Input System - addStrategy("System Input RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Input RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Input RMS C-A", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Input RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Input RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Input RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); + addStrategy("System Input RMS A-B", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Input RMS B-C", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Input RMS C-A", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Input RMS A-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Input RMS B-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Input RMS C-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Input RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Input RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Input RMS Current Phase A", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Input RMS Current Phase B", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Input RMS Current Phase C", new RampStrategy(0.0f, 25.0f, 1000)); - addStrategy("System Input Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); + addStrategy("System Input Frequency", new SingleValueStrategy(60.0f, 2.0f, 1000)); - addStrategy("System Input Power Factor Phs A", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Input Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Input Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); + addStrategy("System Input Power Factor Phs A", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Input Power Factor Phs B", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Input Power Factor Phs C", new SingleValueStrategy(93.0f, 5.0f, 1000)); - addStrategy("System Input Power Phase A", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase B", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase C", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phs A", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phs B", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phs C", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase A", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Power Phase B", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Power Phase C", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Apparent Power Phs A", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Apparent Power Phs B", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Apparent Power Phs C", new RampStrategy(0.0f, 50.0f, 1000)); //Bypass System - addStrategy("Bypass Input Voltage RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("Bypass Input Voltage RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("Bypass Input Voltage RMS C-A", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("Bypass Input Voltage RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("Bypass Input Voltage RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("Bypass Input Voltage RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); + addStrategy("Bypass Input Voltage RMS A-B", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("Bypass Input Voltage RMS B-C", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("Bypass Input Voltage RMS C-A", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("Bypass Input Voltage RMS A-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("Bypass Input Voltage RMS B-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("Bypass Input Voltage RMS C-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); - addStrategy("Bypass Input Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); + addStrategy("Bypass Input Frequency", new SingleValueStrategy(60.0f, 2.0f, 1000)); - addStrategy("Bypass Input Power Phase A", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("Bypass Input Power Phase B", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("Bypass Input Power Phase C", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("Bypass Input Power Phase A", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("Bypass Input Power Phase B", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("Bypass Input Power Phase C", new RampStrategy(0.0f, 25.0f, 1000)); //Output System - addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS C-A", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); + addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS C-A", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Output RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Output RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Output RMS Current Phase A", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Output RMS Current Phase B", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Output RMS Current Phase C", new RampStrategy(0.0f, 25.0f, 1000)); - addStrategy("System Output Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); + addStrategy("System Output Frequency", new SingleValueStrategy(60.0f, 2.0f, 1000)); - addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0f, 5.0f, 1000)); - addStrategy("System Output Power Phase A", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase B", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase C", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs A", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs B", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs C", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Output Power Phase A", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Output Power Phase B", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Output Power Phase C", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs A", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs B", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs C", new RampStrategy(0.0f, 50.0f, 1000)); - addStrategy("Battery Time Remaining", new RampStrategy(480.0F, 0.3f, 1000)); - addStrategy("DC Bus Voltage", new SingleValueStrategy(518.0F, 5.0f, 1000)); + addStrategy("Battery Time Remaining", new RampStrategy(480.0f, 0.3f, 1000)); + addStrategy("DC Bus Voltage", new SingleValueStrategy(518.0f, 5.0f, 1000)); } /** @@ -143,20 +143,20 @@ State* BypassState::update(Equipment* equipment) { } float rating = getPointValue(equipment, "Px Rating"); float load = getPointValue(equipment, "Px Load"); - float real_load = rating * (load/100.f); + float real_load = (rating) * (load/100.0f); Strategy_Behavior* ramp_strat = nullptr; //Input strategies float In_Vab = getPointValue(equipment, "System Input RMS A-B"); ramp_strat = getStrategy("System Input RMS Current Phase A"); - static_cast(ramp_strat)->setTarget(real_load/In_Vab); + static_cast(ramp_strat)->setTarget(real_load); float In_Vbc = getPointValue(equipment, "System Input RMS B-C"); ramp_strat = getStrategy("System Input RMS Current Phase B"); - static_cast(ramp_strat)->setTarget(real_load/In_Vbc); + static_cast(ramp_strat)->setTarget(real_load); float In_Vca = getPointValue(equipment, "System Input RMS C-A"); ramp_strat = getStrategy("System Input RMS Current Phase C"); - static_cast(ramp_strat)->setTarget(real_load/In_Vca); + static_cast(ramp_strat)->setTarget(real_load); float In_Van = getPointValue(equipment, "System Input RMS A-N"); float In_Ia = getPointValue(equipment, "System Input RMS Current Phase A"); @@ -191,13 +191,13 @@ State* BypassState::update(Equipment* equipment) { //Output strategies float Out_Vab = getPointValue(equipment, "System Output RMS A-B"); ramp_strat = getStrategy("System Output RMS Current Phase A"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vab); + static_cast(ramp_strat)->setTarget(real_load); float Out_Vbc = getPointValue(equipment, "System Output RMS B-C"); ramp_strat = getStrategy("System Output RMS Current Phase B"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vbc); + static_cast(ramp_strat)->setTarget(real_load); float Out_Vca = getPointValue(equipment, "System Output RMS C-A"); ramp_strat = getStrategy("System Output RMS Current Phase C"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vca); + static_cast(ramp_strat)->setTarget(real_load); float Out_Van = getPointValue(equipment, "System Output RMS A-N"); float Out_Ia = getPointValue(equipment, "System Output RMS Current Phase A"); @@ -239,11 +239,12 @@ State* BypassState::update(Equipment* equipment) { if (Bat_Percent < 5.0f){ setPointValue(equipment, "UPS Battery Status1", 4.0f); } + setPointValue(equipment, "System Output Power", (real_load * In_Vab)/1000.0f); + setPointValue(equipment, "System Output Apparent Power", (real_load* In_Vab * 0.9f)/1000.0f); // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; } - /** * @brief Logic to execute once when entering the Bypass state. * Sets the "Run Status" for all EC fans to 1 to indicate they are active. diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp index 94036b7..0bdbcb6 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/State_Running.cpp @@ -40,58 +40,60 @@ */ template<> RunningState::RunningState() { - addStrategy("System Input RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Input RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Input RMS C-A", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Input RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Input RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Input RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); + addStrategy("System Input RMS A-B", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Input RMS B-C", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Input RMS C-A", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Input RMS A-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Input RMS B-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Input RMS C-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); - addStrategy("System Input RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Input RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Input RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Input RMS Current Phase A", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Input RMS Current Phase B", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Input RMS Current Phase C", new RampStrategy(0.0f, 25.0f, 1000)); - addStrategy("System Input Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); + addStrategy("System Input Frequency", new SingleValueStrategy(60.0f, 2.0f, 1000)); - addStrategy("System Input Power Factor Phs A", new SingleValueStrategy(93.0F, 0.5f, 1000)); - addStrategy("System Input Power Factor Phs B", new SingleValueStrategy(93.0F, 0.5f, 1000)); - addStrategy("System Input Power Factor Phs C", new SingleValueStrategy(93.0F, 0.5f, 1000)); + addStrategy("System Input Power Factor Phs A", new SingleValueStrategy(93.0f, 0.5f, 1000)); + addStrategy("System Input Power Factor Phs B", new SingleValueStrategy(93.0f, 0.5f, 1000)); + addStrategy("System Input Power Factor Phs C", new SingleValueStrategy(93.0f, 0.5f, 1000)); - addStrategy("System Input Power Phase A", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase B", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Power Phase C", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phs A", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phs B", new RampStrategy(0.0F, 5.0f, 1000)); - addStrategy("System Input Apparent Power Phs C", new RampStrategy(0.0F, 5.0f, 1000)); + addStrategy("System Input Power Phase A", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Power Phase B", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Power Phase C", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Apparent Power Phs A", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Apparent Power Phs B", new RampStrategy(0.0f, 50.0f, 1000)); + addStrategy("System Input Apparent Power Phs C", new RampStrategy(0.0f, 50.0f, 1000)); - addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS C-A", new SingleValueStrategy(480.0F, 5.0f, 1000)); - addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); - addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0F, 5.0f, 1000)); + addStrategy("System Output RMS A-B", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS B-C", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS C-A", new SingleValueStrategy(480.0f, 5.0f, 1000)); + addStrategy("System Output RMS A-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Output RMS B-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); + addStrategy("System Output RMS C-N", new SingleValueStrategy(270.0f, 5.0f, 1000)); - addStrategy("System Output RMS Current Phase A", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Output RMS Current Phase B", new RampStrategy(0.0F, 1.0f, 1000)); - addStrategy("System Output RMS Current Phase C", new RampStrategy(0.0F, 1.0f, 1000)); + addStrategy("System Output RMS Current Phase A", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Output RMS Current Phase B", new RampStrategy(0.0f, 25.0f, 1000)); + addStrategy("System Output RMS Current Phase C", new RampStrategy(0.0f, 25.0f, 1000)); - addStrategy("System Output Frequency", new SingleValueStrategy(60.0F, 2.0f, 1000)); + addStrategy("System Output Frequency", new SingleValueStrategy(60.0f, 2.0f, 1000)); - addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0F, 5.0f, 1000)); - addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0F, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs A", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs B", new SingleValueStrategy(93.0f, 5.0f, 1000)); + addStrategy("System Output Power Factor Phs C", new SingleValueStrategy(93.0f, 5.0f, 1000)); - addStrategy("System Output Power Phase A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Power Phase C", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs A", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs B", new RampStrategy(10.0F, 5.0f, 1000)); - addStrategy("System Output Apparent Power Phs C", new RampStrategy(10.0F, 5.0f, 1000)); + addStrategy("System Output Power Phase A", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Power Phase B", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Power Phase C", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs A", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs B", new RampStrategy(10.0f, 50.0f, 1000)); + addStrategy("System Output Apparent Power Phs C", new RampStrategy(10.0f, 50.0f, 1000)); - addStrategy("DC Bus Voltage", new SingleValueStrategy(518.0F, 5.0f, 1000)); - addStrategy("Battery Time Remaining", new RampStrategy(480.0F, 1.0f, 1000)); - addStrategy("Percentage Load", new RampStrategy(100.0F, 1.0f, 1000)); - + addStrategy("DC Bus Voltage", new SingleValueStrategy(518.0f, 5.0f, 1000)); + addStrategy("Battery Time Remaining", new RampStrategy(480.0f, 1.0f, 1000)); + addStrategy("Percentage Load", new RampStrategy(100.0f, 5.0f, 1000)); + + addStrategy("System Output Power", new SingleValueStrategy(0.0f, 5.0f, 1000)); + addStrategy("System Output Apparent Power", new SingleValueStrategy(0.0f, 5.0f, 1000)); } /** @@ -128,19 +130,22 @@ State* RunningState::update(Equipment* equipment) float rating = getPointValue(equipment, "Px Rating"); float load = getPointValue(equipment, "Px Load"); - float real_load = (rating*1000.0f) * (load/100.f); + float real_load = (rating) * (load/100.0f); Strategy_Behavior* ramp_strat = nullptr; //Input strategies float In_Vab = getPointValue(equipment, "System Input RMS A-B"); ramp_strat = getStrategy("System Input RMS Current Phase A"); - static_cast(ramp_strat)->setTarget(real_load/In_Vab); + static_cast(ramp_strat)->setTarget(real_load); float In_Vbc = getPointValue(equipment, "System Input RMS B-C"); ramp_strat = getStrategy("System Input RMS Current Phase B"); - static_cast(ramp_strat)->setTarget(real_load/In_Vbc); + static_cast(ramp_strat)->setTarget(real_load); float In_Vca = getPointValue(equipment, "System Input RMS C-A"); ramp_strat = getStrategy("System Input RMS Current Phase C"); - static_cast(ramp_strat)->setTarget(real_load/In_Vca); + static_cast(ramp_strat)->setTarget(real_load); + + setPointValue(equipment, "System Output Power", (real_load * In_Vab)/1000.0f); + setPointValue(equipment, "System Output Apparent Power", (real_load* In_Vab * 0.9f)/1000.0f); float In_Van = getPointValue(equipment, "System Input RMS A-N"); float In_Ia = getPointValue(equipment, "System Input RMS Current Phase A"); @@ -169,13 +174,13 @@ State* RunningState::update(Equipment* equipment) //Output strategies float Out_Vab = getPointValue(equipment, "System Output RMS A-B"); ramp_strat = getStrategy("System Output RMS Current Phase A"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vab); + static_cast(ramp_strat)->setTarget(real_load); float Out_Vbc = getPointValue(equipment, "System Output RMS B-C"); ramp_strat = getStrategy("System Output RMS Current Phase B"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vbc); + static_cast(ramp_strat)->setTarget(real_load); float Out_Vca = getPointValue(equipment, "System Output RMS C-A"); ramp_strat = getStrategy("System Output RMS Current Phase C"); - static_cast(ramp_strat)->setTarget(real_load/Out_Vca); + static_cast(ramp_strat)->setTarget(real_load); float Out_Van = getPointValue(equipment, "System Output RMS A-N"); float Out_Ia = getPointValue(equipment, "System Output RMS Current Phase A"); diff --git a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h index 9b11fce..dc93df8 100644 --- a/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h +++ b/src/EPMS/UPS/UPS_Vertiv_APM2_TCP/config.h @@ -23,8 +23,8 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 3, 187); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 3, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 33, 187); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -84,7 +84,7 @@ modbusMap mb_map[] = {IR, 8, 0, "System Input RMS Current Phase B"}, {IR, 9, 0, "System Input RMS Current Phase C"}, {IR_10x, 10, 0, "System Input Frequency"}, - {IR, 11, 0, "System Input Power Factor Phs A"}, + {IR, 11, 0, "System Input Power Factor Phs A"}, //0.01 {IR, 12, 0, "System Input Power Factor Phs B"}, {IR, 13, 0, "System Input Power Factor Phs C"}, {IR_10x, 14, 0, "System Input Power Phase A"}, From 0eaa0232e959a6e003136957bfda5ddcf852ec7c Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Mon, 27 Oct 2025 18:26:08 -0500 Subject: [PATCH 06/51] s --- src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp | 12 ++++++------ src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp | 6 +++--- src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h | 4 ++-- src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h | 3 ++- src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp index 54fbf46..e044cb4 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Running.cpp @@ -66,12 +66,11 @@ template<> State* RunningState::update(Equipment* equipment) { // STATE control, add conditions if change to a different state is needed Serial.println("Running update function"); - Serial.println("Running update function"); float State_Ctrl = getPointValue(equipment, "State Control"); - if (State_Ctrl == 0){ + if (State_Ctrl == 0.0f){ return new StandbyState(); } - if (State_Ctrl == 2){ + if (State_Ctrl == 2.0f){ return new StandbyState(); } // Apply any strategies defined for the standby state @@ -98,8 +97,8 @@ State* RunningState::update(Equipment* equipment) float pf = getPointValue(equipment, "PF"); - float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load * (pf/100.0f))/100.0f; - float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load )/100.0f; + float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load * (pf/100.0f))/100000.0f; + float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load )/10000.0f; setPointValue(equipment, "kW", kw); setPointValue(equipment, "kVA", kva); @@ -119,7 +118,8 @@ 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 - setBitValue(equipment, "CB Position", 1, true); + setBitValue(equipment, "CB Position", 0, true); + setBitValue(equipment, "CB Position", 12, false); } /** diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp index ab732df..7d19437 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp @@ -57,14 +57,14 @@ 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 == 1){ + if (State_Ctrl == 1.0f){ return new RunningState(); } - if (State_Ctrl == 0){ + if (State_Ctrl == 0.0f){ setBitValue(equipment, "CB Position", 12, false); } - if (State_Ctrl == 2){ + if (State_Ctrl == 2.0f){ setBitValue(equipment, "CB Position", 12, true); } // Apply any strategies defined for the standby state diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h b/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h index 018a5ed..b77bc05 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 150); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 33, 154); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -63,7 +63,7 @@ modbusMap mb_map[] = {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 - {IR_LONG, 41, 0, "CB Position"}, //b0 close open b12 tripped + {IR, 41, 0, "CB Position"}, //b0 close open b12 tripped {IR_LONG, 101, 0, "Amps A"}, {IR_LONG, 103, 0, "Amps B"}, {IR_LONG, 105, 0, "Amps C"}, diff --git a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h index 2ee81ea..89915d8 100644 --- a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h @@ -64,11 +64,12 @@ modbusMap mb_map[] = {HR, 10, 0, "Load"}, {HR, 11, 0, "Rating"}, - {IR, 2, 0, "Status"}, + {IR, 2, 0, "Status"}, //bit 2 open-close, {IR, 3, 0, "Amps A"}, {IR, 5, 0, "Amps B"}, {IR, 7, 0, "Amps C"}, {IR, 9, 0, "Amps N"}, + {IR, 13, 0, "Tripped"}, //bit 0 tripped }; //Size of modbus map used in FOR cycles, automatically calculated. diff --git a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h index 07b7b0b..5d19823 100644 --- a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h +++ b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h @@ -64,7 +64,7 @@ modbusMap mb_map[] = {HR, 10, 0, "Load"}, {HR, 11, 0, "Rating"}, - {IR, 207, 0, "CB Position"}, + {IR, 207, 0, "CB Position"}, //bit 9 tripp bit 12 open closed {IR_FLOAT, 215, 0, "Amps A"}, {IR_FLOAT, 217, 0, "Amps B"}, {IR_FLOAT, 219, 0, "Amps C"}, From f5bfd67727c49029a057d9f27540597010fb06c8 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 28 Oct 2025 15:11:45 -0700 Subject: [PATCH 07/51] Added HUM DriSteem RTS RX36 TCP --- platformio.ini | 13 +- .../HUM/HUM_DriSteem_RTS_RX36_TCP/README.md | 51 ++++++++ .../HUM_DriSteem_RTS_RX36_TCP/StateUtils.cpp | 91 +++++++++++++ .../HUM_DriSteem_RTS_RX36_TCP/StateUtils.h | 43 ++++++ .../HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp | 90 +++++++++++++ .../State_Running.cpp | 123 ++++++++++++++++++ .../State_Standby.cpp | 109 ++++++++++++++++ .../HUM/HUM_DriSteem_RTS_RX36_TCP/config.h | 108 +++++++++++++++ .../HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp | 86 ++++++++++++ 9 files changed, 711 insertions(+), 3 deletions(-) create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/README.md create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.cpp create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.h create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Running.cpp create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h create mode 100644 src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index 259c977..5bd4c2f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,10 +11,10 @@ [platformio] -default_envs = PHX3_VFD_ABB_ACH580_RTU ; Select here the name of the configuration you want to download +default_envs = HUM_DriSteem_RTS_RX36_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM50 +upload_port = COM9 [common_env_options] framework = arduino @@ -205,4 +205,11 @@ build_src_filter = -<*> + platform = espressif32 board = dfrobot_firebeetle2_esp32e extends = common_env_options -build_src_filter = -<*> + \ No newline at end of file +build_src_filter = -<*> + + +[env:HUM_DriSteem_RTS_RX36_TCP] +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/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/README.md b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/README.md new file mode 100644 index 0000000..59b4aaa --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/README.md @@ -0,0 +1,51 @@ +# Humidifier Dri-Steem RTS RX-36-1 TCP + +## Brief Introduction +This humidifier receives on/off commands and RH Setpoint from the PLC. +The Space RH register is not used, since there will not be a Space RH sensor wired to the HUM unit. +The RH Setpoint will be determined based on dewpoints in the datahall. See QTS SOO for details. + +## List of Equipment +This configuration has been used for these models: +* **RTS RX-36-1**: 10-28-2025 + +## 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 +Run Mode = 3 (system standby) +Duct RH = 35 +/- 5 +Fill Valve, Drain Valve = 0 +Steam Demand Mass/Pct = 0 +Steam Output Mass/Pct = 0 +If any alarms active or safety interlock = 0 --> FailState +Checks for Run Mode = 1 AND Air Proving Switch = 1 --> RunningState + +### Running State +Run Mode = 1 (auto) +If any alarms active or safety interlock = 0 --> FailState +If Run Mode = 3 or loss of airflow --> StandbyState +Reads RH Setpoint from PLC +DuctRH will dynamically ramp to RH Setpoint +Fill Valve and Drain Valve switch between 0 and 1 (squareStrategy) +Steam Demand Mass between 3-6 (sawStrategy) +Steam Demand Percent between 50-80% (sawStrategy) +Tank Temp = 80 +/- 3 +Steam Output Mass = 4 +/- 1 +Steam Output Percent = 65 +/- 10 +Water Until ADS/Service will ramp down to 0 (initializes at 1500 and 10000) + +### Fail State +Run Mode = 3 (system standby) +Duct RH = 35 +/- 5 +Fill Valve, Drain Valve = 0 +Steam Demand Mass/Pct = 0 +Steam Output Mass/Pct = 0 +When all alarms are cleared and safety interlock = 1 --> StandbyState \ No newline at end of file diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.cpp new file mode 100644 index 0000000..424f2c1 --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.cpp @@ -0,0 +1,91 @@ +/** + * @file StateUtils.cpp + * @brief Implementation of the StateUtils class. + * @author Robert J. Davis + * @date 2025-10-28 + * + * This file contains implementation of utility functions that are used in multiple States. + */ +#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 "ModbusPoints/Modbus_Point.h" +#include "ModbusPoints/Modbus_FloatDecorator.h" +#include "Equipment/Equipment.h" +#include "States/State_Standby.h" +#include "States/State_Running.h" +#include "States/State_Fail.h" +#include "States/State.h" +#include "StateUtils.h" +#include +#include +#if defined(USE_MODBUS_IP) + #include +#else + #include +#endif + +/** + * @brief This function will update the Alarm bits and Safety Interlock state (based on Safety Interlock ON coil - for testing only) + * If the "Clear All Active Alarms" coil is activate, all alarms will be cleared, the Safety Interlock will be set to 1 (ready to operate), + * and the "Manual Clear Alarm Exists" bit will be set to 1. + * The "Alarms Present" (DI 10) will be set to 1 if any alarm is active (or Safety Interlock = 0). This is a register used for + * testing only, and will be used in Standby and Running States to send to FailState. + * + * This function is used in the update() of the Standby, Running, and Fail States. + * +*/ + +void updateAlarms(Equipment* equipment){ + const std::vector alarmDescriptions = { + "Tank Temp Sensor Fail", "Tank Overtemp", "Input RH Out of Range", "Duct RH Out of Range", + "Water Probe Check", "Water Probe Faulty", "Fill Time Excessive", "Refill Time Excessive", + "Tank Not Draining", "Boil Time Excessive" + }; + + // update Safety Interlock state (note: Safety Interlock = 0 means the equipment cannot run- fail safe) + if (equipment->getModbus_Point("Safety Interlock ON")->getValue() == 1){ + equipment->setModbus_Point("Safety Interlock", 0); + } + else equipment->setModbus_Point("Safety Interlock", 1); + + // if "Clear All Active Alarms" bit is 1 --> clear all alarms as well as safety interlock + // if "Clear All Active Alarms" bit is 0 --> if any alarms present set "Alarms Present" register to 1 + if (equipment->getModbus_Point("Clear All Active Alarms")->getValue() == 1){ + for (int i =0; i < alarmDescriptions.size(); ++i) { + equipment->setModbus_Point(alarmDescriptions[i], 0); + } + equipment->setModbus_Point("Safety Interlock ON", 0); + equipment->setModbus_Point("Safety Interlock", 1); + equipment->setModbus_Point("Alarms Present", 0); + equipment->setModbus_Point("Manual Clear Alarm Exists", 1); // the only way to set this back to 0 is manually via Modscan + } + else { + int numAlarms = 0; + for (int i =0; i < alarmDescriptions.size(); ++i) { + Modbus_Point* alarmPoint = equipment->getModbus_Point(alarmDescriptions[i]); + if (alarmPoint->getValue() == 1) numAlarms++; + } + if (equipment->getModbus_Point("Safety Interlock")->getValue() == 0) numAlarms++; + if (numAlarms >= 1) equipment->setModbus_Point("Alarms Present", 1); + else equipment->setModbus_Point("Alarms Present", 0); + } +} + +/** + * @brief This function is used to update the Airflow Proving Switch state (DI 1) + * based on the Safety Interlock ON coil (Coil 2) - this is used for testing purposes only. + * + * This function is used in the update() of the Standby, Running, and Fail States. + * +*/ + +void updateAirflow(Equipment* equipment){ + if (equipment->getModbus_Point("Airflow ON")->getValue() == 1){ + equipment->setModbus_Point("Airflow Proving Switch", 1); + } + else equipment->setModbus_Point("Airflow Proving Switch", 0); +} \ No newline at end of file diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.h b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.h new file mode 100644 index 0000000..e836ae5 --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/StateUtils.h @@ -0,0 +1,43 @@ +/** + * @file config.h + * @brief StateUtils class + * @author Robert J Davis + * @date 2025-10-28 + * + * Defines the StateUtils class, which contains utility functions used in multiple States. + */ + +#pragma once + +#include "ModbusPoints/Modbus_Point.h" +#include "ModbusPoints/Modbus_FloatDecorator.h" +#include "Equipment/Equipment.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 + +template +class State; + +/** + * @brief Updates all alarms, safety interlock, alarms present register. + * @param equipment Pointer to the Equipment instance. + * @return void + */ +void updateAlarms(Equipment* equipment); + +/** + * @brief Updates the Airflow Proving Switch state based on Airflow ON state. + * @param equipment Pointer to the Equipment instance. + * @return void + */ +void updateAirflow(Equipment* equipment); \ No newline at end of file diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp new file mode 100644 index 0000000..14992cc --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp @@ -0,0 +1,90 @@ +/** + * @file State_Fail.cpp + * @brief Implementation of the FailState class. + * @author Robert J Davis + * @date 2025-10-28 + * + * 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" +#include "StateUtils.h" +#if defined(USE_MODBUS_IP) + #include +#else + #include +#endif + +/** + * @brief Constructs a new FailState object with a list of active alarms. + * + * This constructor will have the Duct RH fluctuate around 35% (for visualization purposes). + * + * @param activeAlarms A vector of strings, where each string is the + * description of a Modbus point to be set as an active alarm. + * This parameter is not used in this implementation of the Fail State. + */ +template<> +FailState::FailState(const std::vector& activeAlarms) { + addStrategy("Duct RH", new SingleValueStrategy(35.0f, 5.0f, 1000)); +} + +/** + * @brief Executes the fail state's logic for one update cycle. + * + * Update Alarms states. Stays in FailState until all alarms are cleared --> 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* FailState::update(Equipment* equipment) { + // STATE control, add conditions if change to a different state is needed + Serial.println("Fail update function"); + + updateAlarms(equipment); + + bool alarmsPresent = getPointValue(equipment, "Alarms Present"); + if (!alarmsPresent){ + return new StandbyState(); + } + + _applyStrategies(equipment); + return nullptr; +} + +/** + * @brief Logic to execute once when entering the fail state. + * Sets the Run Mode to 3 (system standby), and appropriate analogs to 0. + * @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..."); + // Ensure Run Mode set to 3 (standby) + setPointValue(equipment, "Run Mode", 3); + setPointValue(equipment, "Fill Valve", 0); + setPointValue(equipment, "Drain Valve", 0); + setPointValue(equipment, "Steam Demand Mass", 0); + setPointValue(equipment, "Steam Demand Percent", 0); + setPointValue(equipment, "Steam Output Mass", 0); + setPointValue(equipment, "Steam Output Percent", 0); +} + +/** + * @brief Logic to execute once when exiting the fail 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/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Running.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Running.cpp new file mode 100644 index 0000000..bafc992 --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Running.cpp @@ -0,0 +1,123 @@ +/** + * @file State_Running.cpp + * @brief Implementation of the RunningState class. + * @author Robert J Davis + * @date 2025-10-28 + * + * 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 "StateUtils.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 including various analog values. Fill and Drain Valves switch between 0 and 1. + * Water Until ADS/Service will ramp down to 0, initialized at 1500 and 10000, respectively. + */ +template<> +RunningState::RunningState() { + addStrategy("Duct RH", new RampStrategy(40.0f, 1.0f, 2000)); + + addStrategy("Fill Valve", new SquareStrategy(1.0f, 0.0f, 5000)); + addStrategy("Drain Valve", new SquareStrategy(0.0f, 1.0f, 4500)); + + addStrategy("Steam Demand Mass", new SawStrategy(3.0f, 6.0f, 1.0f, 2000)); // these values are semi-random for visualization + addStrategy("Steam Demand Percent", new SawStrategy(50.0f, 80.0f, 5.0f, 1000)); // these values are semi-random for visualization + addStrategy("Tank Temp", new SingleValueStrategy(80.0f, 3.0f, 1000)); // these values are semi-random for visualization + addStrategy("Steam Output Mass", new SingleValueStrategy(4.0f, 1.0f, 1000)); // these values are semi-random for visualization + addStrategy("Steam Output Percent", new SingleValueStrategy(65.0f, 10.0f, 1000)); // these values are semi-random for visualization + addStrategy("Water Until ADS", new RampStrategy(0.0f, 1.0f, 2000)); // ramping down to 0 from 1500 + addStrategy("Water Until Service", new RampStrategy(0.0f, 1.0f, 2000)); // ramping down to 0 from 10000 +} + +/** + * @brief Executes the running state's logic for one update cycle. + * + * This method first checks if there are any active alarms --> FailState. + * Also updates Airflow state according to Airflow ON (Coil 1- for testing use only). + * If no alarms are active, checks for loss of airflow or "Run Mode" = 3 (Modscan, but will be from PLC) + * to transition to the Standby state. If no transition is triggered, it updates the + * rampStrategy targetValue of the Duct RH to dynamically ramp up to the Space RH Setpoint (sent from PLC). + * + * @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) { + // Update alarms states and airflow switch state + updateAlarms(equipment); + updateAirflow(equipment); + + // if Alarms are present (as updated in updateAlarms function) --> FailState + bool alarmsPresent = getPointValue(equipment, "Alarms Present"); + if (alarmsPresent){ + std::vector activeAlarmsDesc = {}; // sending a blank string to FailState, b/c that parameter not used in FailState implementation. + return new FailState(activeAlarmsDesc); + } + + // Check for Run Mode and Airflow. If Run Mode = 3 OR Airflow stopped --> StandbyState + int runMode_Command = getPointValue(equipment, "Run Mode"); // Set by PLC + int airflow = getPointValue(equipment, "Airflow Proving Switch"); + if (runMode_Command == 3 || airflow == 0) { + return new StandbyState(); + } + + // Set the Duct RH ramp target value equal to the Space RH Setpoint + float Space_RH_Setpoint = getPointValue(equipment, "Space RH Setpoint"); + float ductRH = getPointValue(equipment, "Duct RH"); + Strategy_Behavior* DuctRH_strat = getStrategy("Duct RH"); + if (DuctRH_strat){ + static_cast(DuctRH_strat)->setTarget(Space_RH_Setpoint); + } + + // Apply any strategies defined for the standby state + _applyStrategies(equipment); + return nullptr; +} + +/** + * @brief Logic to execute once when entering the running state. + * + * Note: do not need to set Run Mode = 1 (auto) since that is required to + * send the unit to Run Mode in the first place. Run Mode will already = 1. + * + * @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..."); +} + +/** + * @brief Logic to execute once when exiting the running 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/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp new file mode 100644 index 0000000..f975167 --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp @@ -0,0 +1,109 @@ +/** + * @file State_Standby.cpp + * @brief Implementation of the StandbyState class. + * @author Robert J Davis + * @date 2025-10-28 + * + * 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 "StateUtils.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 will have + * Duct RH fluctuate around 35% for visualization purposes only. + * + */ +template<> +StandbyState::StandbyState() { + addStrategy("Duct RH", new SingleValueStrategy(35.0f, 5.0f, 1000)); +} + +/** + * @brief Executes the standby state's logic for one update cycle. + * + * This method first checks for state transition commands: + * 1. Updates Alarm states + * 2. Updates Airflow Switch state (based on Airflow ON command - used just for simulation purposes) + * If any Alarms are active or Safety Interlock = 0, send to FailState. + * + * 3. Check if Run Mode = 1 and Airflow Switch = 1, then send to Running State. + * + * If no transition occurs, it applies the strategies defined for the standby state. + * + * @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"); + + updateAlarms(equipment); + updateAirflow(equipment); + + // if Alarms are present (as updated in updateAlarms function) --> FailState + bool alarmsPresent = getPointValue(equipment, "Alarms Present"); + if (alarmsPresent){ + std::vector activeAlarmsDesc = {}; // sending a blank string to FailState, b/c that parameter not used in FailState implementation. + return new FailState(activeAlarmsDesc); + } + + // Check for Run Mode and Airflow Proving Switch. If Run Mode = 1 and there is Airflow --> RunningState + int runMode_Command = getPointValue(equipment, "Run Mode"); // Set by PLC + int airflow = getPointValue(equipment, "Airflow Proving Switch"); + if (airflow == 1 && runMode_Command == 1) { + return new RunningState(); + } + + // Apply any strategies defined for the standby state + _applyStrategies(equipment); + return nullptr; +} + +/** + * @brief Logic to execute once when entering the standby state. + * @param equipment Pointer to the Equipment instance. + */ +template<> +void StandbyState::enterState(Equipment* equipment) { + Serial.println("Enter Standby State..."); + // Set Run Mode to 3 (standby), just in case entered Standby on loss of airflow + setPointValue(equipment, "Run Mode", 3); + setPointValue(equipment, "Fill Valve", 0); + setPointValue(equipment, "Drain Valve", 0); + setPointValue(equipment, "Steam Demand Mass", 0); + setPointValue(equipment, "Steam Demand Percent", 0); + setPointValue(equipment, "Steam Output Mass", 0); + setPointValue(equipment, "Steam Output Percent", 0); +} + +/** + * @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/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h new file mode 100644 index 0000000..b245e29 --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h @@ -0,0 +1,108 @@ +/** + * @file config.h + * @brief Main configuration file for the DriSteem Humidifier (TCP) emulator. + * @author Robert J Davis + * @date 2025-10-27 + * + * 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 = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ + const char *password = "52761492"; /**< @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[] = +{ + {COIL, 0, 0, "Airflow ON"}, // Used for Modscan testing only to set Airflow Proving Switch + {COIL, 1, 0, "Safety Interlock ON"}, // Used for Modscan testing only to trip Safety Interlock + {COIL, 2, 0, "Manual Clear Alarm Exists"}, + {COIL, 3, 0, "Clear All Active Alarms"}, // OCmd_Reset + {COIL, 4, 0, "Tank Temp Sensor Fail"}, + {COIL, 5, 0, "Tank Overtemp"}, + {COIL, 6, 0, "Input RH Out of Range"}, + {COIL, 7, 0, "Duct RH Out of Range"}, + {COIL, 9, 0, "Water Probe Check"}, + {COIL, 10, 0, "Water Probe Faulty"}, + {COIL, 11, 0, "Fill Time Excessive"}, + {COIL, 12, 0, "Refill Time Excessive"}, + {COIL, 13, 0, "Tank Not Draining"}, + {COIL, 14, 0, "Boil Time Excessive"}, + + {DI, 0, 0, "Airflow Proving Switch"}, // 0:open, 1:closed + {DI, 2, 1, "Safety Interlock"}, // 0:open, 1:closed + {DI, 7, 0, "Fill Valve"}, // 0:closed, 1:open + {DI, 8, 0, "Drain Valve"}, // 0:not draining, 1:draining + {DI, 9, 0, "Alarms Present"}, // Used for Modscan testing only - not part of vendor Modbus table + + {IR, 0, 0, "Space RH"}, // Relative_Humidity + {IR, 2, 0, "Duct RH"}, // OSet_CV + {IR, 3, 0, "Steam Demand Mass"}, + {IR, 4, 0, "Steam Demand Percent"}, + {IR, 6, 0, "Tank Temp"}, + {IR, 7, 0, "Steam Output Mass"}, + {IR, 8, 0, "Steam Output Percent"}, + {IR_10x, 9, 1500, "Water Until ADS"}, // 1 = 100 lbs (I know this is 10x function only) + {IR_10x, 10, 10000, "Water Until Service"}, // 1 = 100 lbs (I know this is 10x function only) + + {HR, 0, 3, "Run Mode"}, // Operation_Mode, 1:auto, 2:local standby, 3:system standby, 4:manual drain + {HR, 1, 0, "Space RH Setpoint"}, // Relative_Humidity_SP + {HR, 3, 85, "Duct High Limit Setpoint"}, +}; +//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 \ No newline at end of file diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp @@ -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 +#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); + } +} From 1e4cf1394b3c94d2fae79ce7746fb4fcc7cc295c Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Wed, 29 Oct 2025 12:57:05 -0500 Subject: [PATCH 08/51] save --- platformio.ini | 2 +- .../Breaker/BKR_Susol_ACB_TCP/State_Running.cpp | 9 +++++++-- .../Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp | 13 +++++++++++-- src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h | 8 ++++---- .../Breaker/Susol_Smart_MCCB_TCP/State_Running.cpp | 9 +++++++-- .../Breaker/Susol_Smart_MCCB_TCP/State_Standby.cpp | 11 ++++++++++- src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h | 4 ++-- 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/platformio.ini b/platformio.ini index 06422a6..6282084 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,7 @@ [platformio] -default_envs = BKR_ABB_XT_TCP ; Select here the name of the configuration you want to download +default_envs = BKR_Susol_ACB_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM50 diff --git a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp index 3fb5e0b..a7c0ad2 100644 --- a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Running.cpp @@ -61,7 +61,10 @@ 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){ + if (State_Ctrl == 0.0f){ + return new StandbyState(); + } + if (State_Ctrl == 2.0f){ return new StandbyState(); } @@ -92,7 +95,9 @@ 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); + + setBitValue(equipment, "Status", 2, true); + setBitValue(equipment, "Tripped", 0, false); } diff --git a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp index c7a1db4..b98eb98 100644 --- a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/State_Standby.cpp @@ -57,9 +57,16 @@ 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){ + if (State_Ctrl == 1.0f){ return new RunningState(); } + + if (State_Ctrl == 0.0f){ + setBitValue(equipment, "Tripped", 0, false); + } + if (State_Ctrl == 2.0f){ + setBitValue(equipment, "Tripped", 0, true); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -75,11 +82,13 @@ 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); + setPointValue(equipment, "Amps N", 0.0f); + + setBitValue(equipment, "Status", 2, false); } /** diff --git a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h index 89915d8..66287f0 100644 --- a/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h +++ b/src/EPMS/Breaker/BKR_Susol_ACB_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #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, 238); /**< @brief The static IP address for the device. */ - IPAddress gateway(192, 138, 1, 1); /**< @brief The gateway IP address. */ + const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 33, 149); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Running.cpp b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Running.cpp index 387ac71..c334bdd 100644 --- a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Running.cpp +++ b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Running.cpp @@ -68,7 +68,10 @@ 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){ + if (State_Ctrl == 0.0f){ + return new StandbyState(); + } + if (State_Ctrl == 2.0f){ return new StandbyState(); } // Apply any strategies defined for the standby state @@ -116,7 +119,9 @@ 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", 4096); + + setBitValue(equipment, "CB Position", 12, true); + setBitValue(equipment, "CB Position", 9, false); } diff --git a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Standby.cpp b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Standby.cpp index 13f630c..d839d21 100644 --- a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Standby.cpp +++ b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/State_Standby.cpp @@ -57,9 +57,17 @@ 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){ + if (State_Ctrl == 1.0f){ return new RunningState(); } + + if (State_Ctrl == 0.0f){ + setBitValue(equipment, "CB Position", 9, false); + } + + if (State_Ctrl == 2.0f){ + setBitValue(equipment, "CB Position", 9, true); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -86,6 +94,7 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "Amps A", 0.0f); setPointValue(equipment, "Amps B", 0.0f); setPointValue(equipment, "Amps C", 0.0f); + setBitValue(equipment, "CB Position", 12, false); } /** diff --git a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h index 5d19823..cee6758 100644 --- a/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h +++ b/src/EPMS/Breaker/Susol_Smart_MCCB_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 132); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 33, 141); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -64,7 +64,7 @@ modbusMap mb_map[] = {HR, 10, 0, "Load"}, {HR, 11, 0, "Rating"}, - {IR, 207, 0, "CB Position"}, //bit 9 tripp bit 12 open closed + {IR, 207, 0, "CB Position"}, //bit 9 trip bit 12 open closed {IR_FLOAT, 215, 0, "Amps A"}, {IR_FLOAT, 217, 0, "Amps B"}, {IR_FLOAT, 219, 0, "Amps C"}, From 8157deaae7abfe5448de14a3fa9fa1363dd6fe78 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Thu, 30 Oct 2025 12:32:28 -0700 Subject: [PATCH 09/51] Added General Alarm, VSD Output Freq Added General Alarm, VSD Output Frequency registers. Updated modbus register to actual instead of test registers. --- .../CHILLER/CH_York_YVAA_RTU/StateUtils.cpp | 8 +++ src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 51 ++++++++++--------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp index 696d09a..f695598 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp @@ -41,8 +41,10 @@ void updateAlarms(Equipment* equipment){ Modbus_Point* Sys1FanAlarmCommand = equipment->getModbus_Point("Sys 1 Fan Fault ON"); Modbus_Point* Sys2FanAlarmCommand = equipment->getModbus_Point("Sys 2 Fan Fault ON"); + Modbus_Point* GeneralAlarmCommand = equipment->getModbus_Point("General Alarm ON"); Modbus_Point* Sys1FanAlarm = equipment->getModbus_Point("Sys 1 Fan Fault Alarm"); Modbus_Point* Sys2FanAlarm = equipment->getModbus_Point("Sys 2 Fan Fault Alarm"); + Modbus_Point* GeneralAlarm = equipment->getModbus_Point("General Alarm"); if (Sys1FanAlarmCommand) { Sys1FanAlarm->setValue(Sys1FanAlarmCommand->getValue()); if (Sys1FanAlarmCommand->getValue() == 1){ @@ -57,6 +59,8 @@ void updateAlarms(Equipment* equipment){ } else equipment->setModbus_Point("Sys 2 Fault Code", 0); } + GeneralAlarm->setValue(GeneralAlarmCommand->getValue()); + } /** @@ -74,6 +78,9 @@ void updateFreeCooling(Equipment* equipment){ Modbus_Point* FreeCoolingCommand = equipment->getModbus_Point("Free Cooling Mode ON"); Modbus_Point* FreeCoolingMode = equipment->getModbus_Point("Free Cooling Mode"); Modbus_Point* FreeCoolingValve = equipment->getModbus_Point("Free Cooling Valve"); + FreeCoolingMode->setValue(FreeCoolingCommand->getValue()); + FreeCoolingValve->setValue(FreeCoolingCommand->getValue()); + /** if (FreeCoolingCommand->getValue() == 1) { FreeCoolingMode->setValue(1); FreeCoolingValve->setValue(1); @@ -82,4 +89,5 @@ void updateFreeCooling(Equipment* equipment){ FreeCoolingMode->setValue(0); FreeCoolingValve->setValue(0); } + */ } \ No newline at end of file diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index fbd900f..16eb93f 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -54,25 +54,30 @@ */ modbusMap mb_map[] = { - {COIL, 0, 0, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only - {COIL, 4, 0, "Sys 2 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only - {COIL, 5, 0, "Free Cooling Mode ON"}, // Use in Modscan - Used for Arduino simulation only + {COIL, 0, 0, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. + {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY + {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY + {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE + {COIL, 4, 0, "Sys 2 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE + {COIL, 5, 0, "Free Cooling Mode ON"}, // Use in Modscan - Used for Arduino simulation only + {COIL, 6, 0, "General Alarm ON"}, // Use in Modscan - Used for Arduino simulation only - {DI, 0, 0, "Sys 1 Fan Fault Alarm"}, - {DI, 1, 0, "Sys 2 Fan Fault Alarm"}, + {DI, 65, 0, "General Alarm"}, // part of Modbus map, but not included in code --> INDICATION ONLY + {DI, 174, 0, "Sys 1 Fan Fault Alarm"}, + {DI, 175, 0, "Sys 2 Fan Fault Alarm"}, - {HR, 0, 0, "Chiller Status"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {HR, 1, 0, "Chiller Temp Setpoint"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {HR, 2, 0, "Supply Temp"}, // Use in Modscan - Hard IO in SCP (PICS?), Used for Arduino simulation only - {HR, 3, 0, "Return Temp"}, // Use in Modscan - Hard IO in SCP (PICS?), Used for Arduino simulation only + {IR, 130, 0, "Free Cooling Mode"}, + {IR, 165, 0, "Free Cooling Valve"}, - {HR, 4, 70, "System CHW Out"}, - {HR, 5, 70, "System CHW In"}, - {HR, 7, 0, "Sys 1 Condenser Temp"}, - {HR, 9, 0, "Ambient Temp"}, + {HR, 0, 0, "Chiller Status"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only + {HR, 1, 0, "Chiller Temp Setpoint"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only + {HR, 2, 0, "Supply Temp"}, // Use in Modscan - Hard IO in SCP (PICS?), Used for Arduino simulation only + {HR, 3, 0, "Return Temp"}, // Use in Modscan - Hard IO in SCP (PICS?), Used for Arduino simulation only + + {HR, 4, 70, "System CHW Out"}, + {HR, 5, 70, "System CHW In"}, + {HR, 7, 0, "Sys 1 Condenser Temp"}, + {HR, 9, 0, "Ambient Temp"}, {HR, 11, 0, "Sys 1 Oil Pressure"}, {HR, 12, 0, "Sys 1 Suction Pressure"}, @@ -88,6 +93,8 @@ modbusMap mb_map[] = {HR, 24, 0, "Sys 2 Run Hours"}, {HR, 25, 0, "Sys 2 Starts"}, + {HR, 26, 0, "VSD Output Frequency"}, // part of Modbus map, but not included in code + {HR, 29, 77, "Sys 1 Operational Code"}, {HR, 30, 0, "Sys 1 Fault Code"}, {HR, 31, 77, "Sys 2 Operational Code"}, @@ -95,13 +102,11 @@ modbusMap mb_map[] = {HR, 39, 0, "Local Leaving Temp Setpoint"}, - {HR, 40, 0, "Sys 1 Fan KW"}, - {HR, 41, 0, "Sys 1 Compressor KW"}, - {HR, 42, 0, "Sys 2 Fan KW"}, - {HR, 43, 0, "Sys 2 Compressor KW"}, - {HR, 49, 0, "Sys 2 Condenser Temp"}, - {HR, 50, 0, "Free Cooling Mode"}, - {HR, 51, 0, "Free Cooling Valve"}, + {HR, 49, 0, "Sys 2 Condenser Temp"}, + {HR, 140, 0, "Sys 1 Fan KW"}, + {HR, 141, 0, "Sys 1 Compressor KW"}, + {HR, 142, 0, "Sys 2 Fan KW"}, + {HR, 143, 0, "Sys 2 Compressor KW"}, }; //Size of modbus map used in FOR cycles, automatically calculated. From 12e397c855e6c5c00f5f9207ba54d30ed0379158 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Thu, 30 Oct 2025 16:53:26 -0500 Subject: [PATCH 10/51] save --- platformio.ini | 9 +- .../State_Running.cpp | 115 ++++++------- .../CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/config.h | 159 +++++++++--------- 3 files changed, 137 insertions(+), 146 deletions(-) diff --git a/platformio.ini b/platformio.ini index 6282084..1999fbd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,7 @@ [platformio] -default_envs = BKR_Susol_ACB_TCP ; Select here the name of the configuration you want to download +default_envs = CRAH_PETRA_PAHHC_600_C6_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM50 @@ -36,6 +36,13 @@ extends = common_env_options build_flags = -D USE_MODBUS_IP ;Importat configuration, this flags is used to configure the program build_src_filter = -<*> + ;Add the specific folder path here ;---------------------------------------------------------------------------------------------------- +[env:CRAH_PETRA_PAHHC_600_C6_TCP] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = -D USE_MODBUS_IP +build_src_filter = -<*> + + [env:POD_MBB_Power_Meter_TCP] platform = espressif32 board = dfrobot_firebeetle2_esp32e diff --git a/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/State_Running.cpp index b0f5399..6a2c459 100644 --- a/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/State_Running.cpp @@ -38,16 +38,26 @@ */ template<> RunningState::RunningState() { - addStrategy("CW Valve Position", new PIDStrategy("RAT Setpoint", 1000, "RAT")); - addStrategy("Operating Hours EC Fan #1", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #2", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #3", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #4", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #5", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #6", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #7", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #8", new TotalizerStrategy(10000)); - addStrategy("Operating Hours EC Fan #9", new TotalizerStrategy(10000)); + addStrategy("CW Valve Position", new PIDStrategy("SAT Setpoint", 2000, "SAT Reading")); + addStrategy("SAT Reading", new SingleValueStrategy(0.0f, 3.0f, 1000)); + addStrategy("Speed EC Fan #1", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #2", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #3", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #4", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #5", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #6", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #7", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #8", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Speed EC Fan #9", new RampStrategy(0.0f, 500.0f, 1000)); + addStrategy("Operating Hours EC Fan #1", new TotalizerStrategy(1100)); + addStrategy("Operating Hours EC Fan #2", new TotalizerStrategy(1200)); + addStrategy("Operating Hours EC Fan #3", new TotalizerStrategy(1300)); + addStrategy("Operating Hours EC Fan #4", new TotalizerStrategy(1250)); + addStrategy("Operating Hours EC Fan #5", new TotalizerStrategy(1350)); + addStrategy("Operating Hours EC Fan #6", new TotalizerStrategy(1450)); + addStrategy("Operating Hours EC Fan #7", new TotalizerStrategy(1150)); + addStrategy("Operating Hours EC Fan #8", new TotalizerStrategy(1180)); + addStrategy("Operating Hours EC Fan #9", new TotalizerStrategy(1340)); } /** @@ -74,63 +84,36 @@ State* RunningState::update(Equipment* equipment) return new StandbyState(); } - Modbus_Point* faultCode = equipment->getModbus_Point("Fault Code"); - int faultCodeValue = faultCode ? faultCode->getValue() : 0; - switch (faultCodeValue){ - case 1: - return new FailState({"Alarm SAT Sensor Fault"}); - case 2: - return new FailState({"Alarm RAH Sensor Fault"}); - case 3: - return new FailState({"Alarm RAT Sensor Fault"}); - case 4: - return new FailState({"Alarm Filter DP Sensor Fault"}); - case 5: - return new FailState({"Alarm Flooding"}); - case 6: - return new FailState({"Alarm Dirty Filter"}); - case 7: - return new FailState({"Alarm High RAT"}); - case 8: - return new FailState({"Alarm Low RAT"}); - case 9: - return new FailState({"Alarm High SAT"}); - case 10: - return new FailState({"Alarm Low SAT"}); - case 11: - return new FailState({"Alarm High RAH"}); - case 12: - return new FailState({"Alarm Low RAH"}); - case 13: - return new FailState({"Alarm Phase Failure"}); - case 14: - return new FailState({"Alarm Condensate Pump"}); - case 15: - return new FailState({"Alarm Smoke"}); - case 16: - return new FailState({"Alarm Fire"}); - case 17: - return new FailState({"Alarm EC Fan #1"}); - case 18: - return new FailState({"Alarm EC Fan #2"}); - case 19: - return new FailState({"Alarm EC Fan #3"}); - case 20: - return new FailState({"Alarm EC Fan #4"}); - case 21: - return new FailState({"Alarm EC Fan #5"}); - case 22: - return new FailState({"Alarm EC Fan #6"}); - case 23: - return new FailState({"Alarm EC Fan #7"}); - case 24: - return new FailState({"Alarm EC Fan #8"}); - case 25: - return new FailState({"Alarm EC Fan #9"}); - default: - break; - } + float rat = getPointValue(equipment, "RAT"); + setPointValue(equipment, "RAT Reading", rat); + float speed = getPointValue(equipment, "Setting EC Fan Speed"); + Strategy_Behavior* fan1_rs = getStrategy("Speed EC Fan #1"); + static_cast(fan1_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan2_rs = getStrategy("Speed EC Fan #2"); + static_cast(fan2_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan3_rs = getStrategy("Speed EC Fan #3"); + static_cast(fan3_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan4_rs = getStrategy("Speed EC Fan #4"); + static_cast(fan4_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan5_rs = getStrategy("Speed EC Fan #5"); + static_cast(fan5_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan6_rs = getStrategy("Speed EC Fan #6"); + static_cast(fan6_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan7_rs = getStrategy("Speed EC Fan #7"); + static_cast(fan7_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan8_rs = getStrategy("Speed EC Fan #8"); + static_cast(fan8_rs)->setTarget(4200.0f * (speed /100.0f)); + Strategy_Behavior* fan9_rs = getStrategy("Speed EC Fan #9"); + static_cast(fan9_rs)->setTarget(4200.0f * (speed /100.0f)); + + + + float value = getPointValue(equipment, "CW Valve Position"); + Serial.printf("CW Valve Position: %0.2f\n", value); + float sat_setpoint = getPointValue(equipment, "SAT Setpoint"); + Strategy_Behavior* sat_svs = getStrategy("SAT Reading"); + static_cast(sat_svs)->setSetpoint(sat_setpoint); // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/config.h b/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/config.h index bd4ad09..d115f19 100644 --- a/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/config.h +++ b/src/BMS/CRAH/CRAH_PETRA_PAHHC_600_C6_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #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. */ + const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 33, 11); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -60,81 +60,82 @@ */ modbusMap mb_map[] = { - {HR, 15, 0, "State Control"}, //Internal to control from Modscan - {HR, 16, 0, "Fault Code"}, - {HR_FLOAT, 18, 0, "RAT"}, //Internal Fault code from Modscan - {HR_FLOAT, 1, 0, "SAT Setpoint"}, - {HR_FLOAT, 681, 0, "RAT Setpoint"}, - {HR_FLOAT, 111, 0, "High RAT Limit"}, - {HR_FLOAT, 114, 0, "Low RAT Limit"}, - {HR_FLOAT, 118, 0, "High SAT Limit"}, - {HR_FLOAT, 122, 0, "Low SAT Limit"}, - {HR_FLOAT, 685, 0, "High RAH Limit"}, - {HR_FLOAT, 689, 0, "Low RAH Limit"}, - {HR, 5, 0, "Setting the EC Fan Max Speed"}, - {HR, 695, 0, "Setting the EC Fan Min Speed"}, - {HR_FLOAT, 693, 0, "Setting Room Temp"}, - {HR, 691, 0, "Setting EC Fan Speed "}, - {DI, 146, 0, "Alarm SAT Sensor Fault"}, - {DI, 1246, 0, "Alarm RAH Sensor Fault"}, - {DI, 1245, 0, "Alarm RAT Sensor Fault"}, - {DI, 1250, 0, "Alarm Filter DP Sensor Fault"}, - {DI, 51, 0, "Alarm Flooding"}, - {DI, 1096, 0, "Alarm Dirty Filter"}, - {DI, 1367, 0, "Alarm High RAT"}, - {DI, 1099, 0, "Alarm Low RAT"}, - {DI, 118, 0, "Alarm High SAT"}, - {DI, 122, 0, "Alarm Low SAT"}, - {DI, 1307, 0, "Alarm High RAH"}, - {DI, 1308, 0, "Alarm Low RAH"}, - {DI, 1342, 0, "Alarm Common"}, - {DI, 148, 0, "Alarm Phase Failure"}, - {DI, 1370, 0, "Alarm Condensate Pump"}, - {DI, 1368, 0, "Alarm Smoke"}, - {DI, 1369, 0, "Alarm Fire"}, - {DI, 131, 0, "Alarm EC Fan #1"}, - {DI, 132, 0, "Alarm EC Fan #2"}, - {DI, 133, 0, "Alarm EC Fan #3"}, - {DI, 134, 0, "Alarm EC Fan #4"}, - {DI, 135, 0, "Alarm EC Fan #5"}, - {DI, 136, 0, "Alarm EC Fan #6"}, - {DI, 1360, 0, "Alarm EC Fan #7"}, - {DI, 1361, 0, "Alarm EC Fan #8"}, - {DI, 1362, 0, "Alarm EC Fan #9"}, - {DI, 138, 0, "Run Status EC Fan #1"}, - {DI, 139, 0, "Run Status EC Fan #2"}, - {DI, 140, 0, "Run Status EC Fan #3"}, - {DI, 141, 0, "Run Status EC Fan #4"}, - {DI, 142, 0, "Run Status EC Fan #5"}, - {DI, 143, 0, "Run Status EC Fan #6"}, - {DI, 1363, 0, "Run Status EC Fan #7"}, - {DI, 1364, 0, "Run Status EC Fan #8"}, - {DI, 1365, 0, "Run Status EC Fan #9"}, - {IR_FLOAT, 99, 0, "SAT Reading"}, - {IR_FLOAT, 70, 0, "RAH Reading"}, - {IR_FLOAT, 101, 0, "RAT Reading"}, - {IR_FLOAT, 106, 0, "Filter DP Reading"}, - {IR_FLOAT, 496, 0, "CW Valve Position"}, - {IR, 53, 0, "Speed EC Fan #1"}, - {IR, 228, 0, "Speed EC Fan #2"}, - {IR, 229, 0, "Speed EC Fan #3"}, - {IR, 230, 0, "Speed EC Fan #4"}, - {IR, 231, 0, "Speed EC Fan #5"}, - {IR, 232, 0, "Speed EC Fan #6"}, - {IR, 678, 0, "Speed EC Fan #7"}, - {IR, 679, 0, "Speed EC Fan #8"}, - {IR, 680, 0, "Speed EC Fan #9"}, - {IR, 274, 0, "Operating Hours EC Fan #1"}, - {IR, 233, 0, "Operating Hours EC Fan #2"}, - {IR, 244, 0, "Operating Hours EC Fan #3"}, - {IR, 235, 0, "Operating Hours EC Fan #4"}, - {IR, 236, 0, "Operating Hours EC Fan #5"}, - {IR, 245, 0, "Operating Hours EC Fan #6"}, - {IR, 486, 0, "Operating Hours EC Fan #7"}, - {IR, 487, 0, "Operating Hours EC Fan #8"}, - {IR, 488, 0, "Operating Hours EC Fan #9"}, - {COIL, 301, 0, "ON/OFF Command By BMS"}, - {COIL, 302, 0, "Enable Off By Supervisory"}, + {HR, 13, 0, "Delta"}, + {HR, 14, 0, "State Control"}, //Internal to control from Modscan + {HR, 15, 0, "Fault Code"}, + {HR_FLOAT, 17, 0, "RAT"}, //Internal Fault code from Modscan + {HR_FLOAT, 0, 0, "SAT Setpoint"}, + {HR_FLOAT, 680, 0, "RAT Setpoint"}, + {HR_FLOAT, 110, 0, "High RAT Limit"}, + {HR_FLOAT, 113, 0, "Low RAT Limit"}, + {HR_FLOAT, 117, 0, "High SAT Limit"}, + {HR_FLOAT, 121, 0, "Low SAT Limit"}, + {HR_FLOAT, 684, 0, "High RAH Limit"}, + {HR_FLOAT, 688, 0, "Low RAH Limit"}, + {HR, 4, 0, "Setting the EC Fan Max Speed"}, + {HR, 694, 0, "Setting the EC Fan Min Speed"}, + {HR_FLOAT, 692, 0, "Setting Room Temp"}, + {HR_FLOAT, 690, 0, "Setting EC Fan Speed"}, + {DI, 145, 0, "Alarm SAT Sensor Fault"}, + {DI, 1245, 0, "Alarm RAH Sensor Fault"}, + {DI, 1244, 0, "Alarm RAT Sensor Fault"}, + {DI, 1249, 0, "Alarm Filter DP Sensor Fault"}, + {DI, 50, 0, "Alarm Flooding"}, + {DI, 1095, 0, "Alarm Dirty Filter"}, + {DI, 1366, 0, "Alarm High RAT"}, + {DI, 1098, 0, "Alarm Low RAT"}, + {DI, 117, 0, "Alarm High SAT"}, + {DI, 121, 0, "Alarm Low SAT"}, + {DI, 1306, 0, "Alarm High RAH"}, + {DI, 1307, 0, "Alarm Low RAH"}, + {DI, 1341, 0, "Alarm Common"}, + {DI, 147, 0, "Alarm Phase Failure"}, + {DI, 1369, 0, "Alarm Condensate Pump"}, + {DI, 1367, 0, "Alarm Smoke"}, + {DI, 1368, 0, "Alarm Fire"}, + {DI, 130, 0, "Alarm EC Fan #1"}, + {DI, 131, 0, "Alarm EC Fan #2"}, + {DI, 132, 0, "Alarm EC Fan #3"}, + {DI, 133, 0, "Alarm EC Fan #4"}, + {DI, 134, 0, "Alarm EC Fan #5"}, + {DI, 135, 0, "Alarm EC Fan #6"}, + {DI, 1359, 0, "Alarm EC Fan #7"}, + {DI, 1360, 0, "Alarm EC Fan #8"}, + {DI, 1361, 0, "Alarm EC Fan #9"}, + {DI, 137, 0, "Run Status EC Fan #1"}, + {DI, 138, 0, "Run Status EC Fan #2"}, + {DI, 139, 0, "Run Status EC Fan #3"}, + {DI, 140, 0, "Run Status EC Fan #4"}, + {DI, 141, 0, "Run Status EC Fan #5"}, + {DI, 142, 0, "Run Status EC Fan #6"}, + {DI, 1362, 0, "Run Status EC Fan #7"}, + {DI, 1363, 0, "Run Status EC Fan #8"}, + {DI, 1364, 0, "Run Status EC Fan #9"}, + {IR_FLOAT, 98, 0, "SAT Reading"}, + {IR_FLOAT, 69, 0, "RAH Reading"}, + {IR_FLOAT, 100, 0, "RAT Reading"}, + {IR_FLOAT, 105, 0, "Filter DP Reading"}, + {IR_FLOAT, 495, 0, "CW Valve Position"}, + {IR, 52, 0, "Speed EC Fan #1"}, + {IR, 227, 0, "Speed EC Fan #2"}, + {IR, 228, 0, "Speed EC Fan #3"}, + {IR, 229, 0, "Speed EC Fan #4"}, + {IR, 230, 0, "Speed EC Fan #5"}, + {IR, 231, 0, "Speed EC Fan #6"}, + {IR, 677, 0, "Speed EC Fan #7"}, + {IR, 678, 0, "Speed EC Fan #8"}, + {IR, 679, 0, "Speed EC Fan #9"}, + {IR, 273, 0, "Operating Hours EC Fan #1"}, + {IR, 232, 0, "Operating Hours EC Fan #2"}, + {IR, 243, 0, "Operating Hours EC Fan #3"}, + {IR, 234, 0, "Operating Hours EC Fan #4"}, + {IR, 235, 0, "Operating Hours EC Fan #5"}, + {IR, 244, 0, "Operating Hours EC Fan #6"}, + {IR, 485, 0, "Operating Hours EC Fan #7"}, + {IR, 486, 0, "Operating Hours EC Fan #8"}, + {IR, 487, 0, "Operating Hours EC Fan #9"}, + {COIL, 300, 0, "ON/OFF Command By BMS"}, + {COIL, 301, 0, "Enable Off By Supervisory"}, {COIL, 264, 0, "Alarm Reset"} }; //Size of modbus map used in FOR cycles, automatically calculated. From b6c00d32e23dbd616efd325c9dfc321c3426e080 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Fri, 31 Oct 2025 10:40:19 -0500 Subject: [PATCH 11/51] ATS update --- .../ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp | 11 ++++++++++- .../ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp | 13 ++++++++++++- src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h | 1 + .../ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp | 10 ++++++++++ .../ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp | 10 ++++++++++ src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h | 1 + 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp index accba63..8075096 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Running.cpp @@ -100,7 +100,16 @@ State* RunningState::update(Equipment* equipment) float pf = getPointValue(equipment, "Power Factor"); float a_pwr = pwr * (pf/100.0f); setPointValue(equipment, "Total Apparent Power", a_pwr*1000.0f); - + + float preferred = getPointValue(equipment, "ATS_Preferred"); + if (preferred == 1.0f){ + setPointValue(equipment, "Source 1 Preferred", 1.0f); + setPointValue(equipment, "Source 2 Preferred", 0.0f); + } + if (preferred == 2.0f){ + setPointValue(equipment, "Source 1 Preferred", 0.0f); + setPointValue(equipment, "Source 2 Preferred", 1.0f); + } _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp index 39347b3..100cf86 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/State_Standby.cpp @@ -97,7 +97,18 @@ State* StandbyState::update(Equipment* equipment) float a_pwr = pwr * (pf/100.0f); setPointValue(equipment, "Total Apparent Power", a_pwr*1000.0f); - + /*setPointValue(equipment, "S2 kW", kw); + setPointValue(equipment, "S2 MWh", mwh);*/ + + float preferred = getPointValue(equipment, "ATS_Preferred"); + if (preferred == 1.0f){ + setPointValue(equipment, "Source 1 Preferred", 1.0f); + setPointValue(equipment, "Source 2 Preferred", 0.0f); + } + if (preferred == 2.0f){ + setPointValue(equipment, "Source 1 Preferred", 0.0f); + setPointValue(equipment, "Source 2 Preferred", 1.0f); + } _applyStrategies(equipment); return nullptr; } diff --git a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h index b781b9e..6df64d2 100644 --- a/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h +++ b/src/EPMS/ATS/ATS_Eaton_ATC900_RPD_TCP/config.h @@ -60,6 +60,7 @@ */ modbusMap mb_map[] = { + {HR, 8, 0, "ATS_Preferred"}, //Internal to control from Modscan {HR, 9, 0, "ATS_Source"}, //Internal to control from Modscan {HR, 10, 0, "ATS_Load"}, //Internal Fault code from Modscan {HR, 11, 0, "ATS_Rating"}, //Internal Fault code from Modscan diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp index 9dafbf6..cd10304 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Running.cpp @@ -105,6 +105,16 @@ State* RunningState::update(Equipment* equipment) setPointValue(equipment, "S2 kW", kw); setPointValue(equipment, "S2 MWh", mwh); + float preferred = getPointValue(equipment, "ATS_Preferred"); + if (preferred == 1.0f){ + setBitValue(equipment, "Source Preferred", 9, true); + setBitValue(equipment, "Source Preferred", 8, false); + } + if (preferred == 2.0f){ + setBitValue(equipment, "Source Preferred", 9, false); + setBitValue(equipment, "Source Preferred", 8, true); + } + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp index 10fd829..cb1a547 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/State_Standby.cpp @@ -96,6 +96,16 @@ State* StandbyState::update(Equipment* equipment) float kw = (1.732f * ((real_v_AB + real_v_BC + real_v_CA)/3.0f) * sim_load * pf)*10; float mwh = kw *600.0f; + float preferred = getPointValue(equipment, "ATS_Preferred"); + if (preferred == 1.0f){ + setBitValue(equipment, "Source Preferred", 9, true); + setBitValue(equipment, "Source Preferred", 8, false); + } + if (preferred == 2.0f){ + setBitValue(equipment, "Source Preferred", 9, false); + setBitValue(equipment, "Source Preferred", 8, true); + } + setPointValue(equipment, "S1 kW", kw); setPointValue(equipment, "S1 MWh", mwh); _applyStrategies(equipment); diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h index 7b5d59e..3f7bcf0 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h @@ -60,6 +60,7 @@ */ modbusMap mb_map[] = { + {HR, 8, 0, "ATS_Preferred"}, //Internal to control from Modscan {HR, 9, 0, "ATS_Source"}, //Internal to control from Modscan {HR, 10, 0, "ATS_Load"}, {HR, 11, 0, "ATS_Rating"}, //Internal Fault code from Modscan From 25688908f2799dbe518b3420f103e1b069f6d913 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 31 Oct 2025 10:34:07 -0700 Subject: [PATCH 12/51] Added General Alarm, Fail State Added General Alarm, Fail State, changed some registers to 10x. --- src/BMS/CHILLER/CH_York_YVAA_RTU/README.md | 55 ++++++++++---- .../CHILLER/CH_York_YVAA_RTU/StateUtils.cpp | 30 ++++---- .../CHILLER/CH_York_YVAA_RTU/State_Fail.cpp | 56 +++++++++++---- .../CH_York_YVAA_RTU/State_Running.cpp | 33 ++++++--- .../CH_York_YVAA_RTU/State_Standby.cpp | 14 +++- src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 71 +++++++++---------- 6 files changed, 169 insertions(+), 90 deletions(-) diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md b/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md index 0d95a1b..83edb97 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md @@ -1,16 +1,12 @@ # CHILLER YORK YVAA 0428IOK46BAVTXX TCP ## Brief Introduction - -*** NOTE! *** -This code has not been verified with Chiller and Chiller Manager PLC program. -It is a best-guess based on a preliminary review of Chiller PLC program, but -has yet to be fully vetted and local tested with PLC programs. - -Chiller receives Temp SP and Enable from PLC (Modscan) -Alarms are also simulated via Modscan, though those signals will be internal to Chiller -Many hard IO points are simulated using Modscan. -Assumes all Modbus points are for monitoring only and go to Ignition - not sent to PLC +Chiller receives Chiller Temp SP and Enable from PLC. The Supply Temp will ramp to Chiller Temp SP in Run Mode. +Alarms are also simulated via Modscan, though those signals will be internal to Chiller. +Hard IO points simulated with Modscan: Sys 1 Alarm, Sys 2 Alarm. +Chiller Status is sent back to PLC. +In practice, all Modbus points are for monitoring only and go to Ignition - not sent to PLC. +For the sake of simulation, some hard IO points (simulated as Modbus points) will go back to PLC for feedback or will be sent from PLC to Arduino. ## List of Equipment This cofiguration has been used for these models: @@ -24,20 +20,51 @@ The code is written for an ESP8266/ESP32-style microcontroller with WiFi capabil --- ## States and Strategies -Updates Alarms States. If any active alarms --> FailState +Updates Alarms States. Only the Sys 1 Fan Fault or Sys 2 Fan Fault will end unit --> FailState +Sys 1 Alarm, Sys 2 Alarm, and General Alarm will annunciate only, will not stop the unit (this is an assumption the program follows, may differ in field). Updates Free Cooling Mode: Free Cooling Mode is activated using a coil, for simulation purposes only. Modbus points are simulated, mostly with a SingleValue strategy for image verification in Ignition. -While in RunningState, the Supply Temp dynamically ramps to the Supply Temp SP sent from PLC (Modscan) +While in RunningState, the Supply Temp dynamically ramps to the Supply Temp SP sent from PLC (or Modscan) The CHW In and CHW Out temperature values also dynamically ramp to match the Return and Supply Temps. ### Standby State * **Chiller Status**: set to 0 * **Operational Code**: set to 77 * **Chiller Start Command**: set to 0 +Supply Temp = 80 +/- 1 +Return Temp = 80 +/- 1 +System CHW Out = 80 +/- 1 +System CHW In = 80 +/- 1 +Ambient Temp = 1-- +/- 1 +Sys 1, 2 Oil Pressure = 420 +/- 1 +Sys 1, 2 Suction Pressure = 70 +/- 1 +Sys 1, 2 Discharge Pressure = 70 +/- 1 +Sys 1, 2 Condenser Temp = 124 +/- 1 ### Running State * **Chiller status**: set to 1 -* **Supply Temperature**: **Ramp Strategy** ramps to Temp Setpoint from PLC (Modscan) +* **Operational Code**: set to 78 (running) +* **Supply Temperature**: **Ramp Strategy** ramps to Chiller Temp Setpoint from PLC (Modscan) +Supply Temp dynamically ramps to Chiller Temp Setpoint as sent from PLC (or Modscan) +Return Temp sawStrategy (79-83) +System CHW Out dynamically ramps to follow Supply Temp +System CHW In dynamically ramps to follow Return Temp +Ambient Temp = 1-- +/- 1 +Sys 1, 2 Oil Pressure = 450 +/- 5 +Sys 1, 2 Suction Pressure = 70 +/- 2 +Sys 1, 2 Discharge Pressure = 375 +/- 4 +Sys 1, 2 Compressor Pct FLA = 93 +/- 2 +Sys 1, 2 Condenser Temp = 125 +/- 5 +Sys 1 Fan kW = 35 +/- 2 +Sys 2 Fan kW = 23 +/- 2 +Sys 1 Compressor kW = 304 +/- 5 +Sys 2 Compressor kW = 198 +/- 5 ### Fail State -* **Chiller Status**: set to 0 \ No newline at end of file +All values match that of Standby State. +The difference is in Fail State, if a Start Command is sent it will not start the Chiller. +All faults must be cleared, then unit transitions to Standby State. +* **Chiller Status**: set to 0 +* **Operational Code**: set to 77 +* **Chiller Start Command**: set to 0 +All analog values same as in Standby State \ No newline at end of file diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp index f695598..434a1f3 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/StateUtils.cpp @@ -32,19 +32,19 @@ * @brief Updates Alarms states * * This function will update the Alarm status DI bits according to the Alarm Commands from Coils (Modscan) - * The appropriate Fault Code will also be set to 56 (Condenser Fan VSD Warning) + * The appropriate Fault Code will also be set to 56 (Condenser Fan VSD Warning). + * Also updates the General Alarm bit. If any alarms are active, General Alarm --> 1, else 0. * * This is a function used in the update() of the Standby, Running, and Fail States. * */ void updateAlarms(Equipment* equipment){ + // Updates Sys 1, 2 Fan Fault Alarms with associated Fault Code Modbus_Point* Sys1FanAlarmCommand = equipment->getModbus_Point("Sys 1 Fan Fault ON"); Modbus_Point* Sys2FanAlarmCommand = equipment->getModbus_Point("Sys 2 Fan Fault ON"); - Modbus_Point* GeneralAlarmCommand = equipment->getModbus_Point("General Alarm ON"); Modbus_Point* Sys1FanAlarm = equipment->getModbus_Point("Sys 1 Fan Fault Alarm"); Modbus_Point* Sys2FanAlarm = equipment->getModbus_Point("Sys 2 Fan Fault Alarm"); - Modbus_Point* GeneralAlarm = equipment->getModbus_Point("General Alarm"); if (Sys1FanAlarmCommand) { Sys1FanAlarm->setValue(Sys1FanAlarmCommand->getValue()); if (Sys1FanAlarmCommand->getValue() == 1){ @@ -59,8 +59,20 @@ void updateAlarms(Equipment* equipment){ } else equipment->setModbus_Point("Sys 2 Fault Code", 0); } - GeneralAlarm->setValue(GeneralAlarmCommand->getValue()); + // Update General Alarm (if any Alarm is active, make general alarm active) + const std::vector alarmDescriptions = { + "Sys 1 Alarm", "Sys 2 Alarm", "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm" + }; + int numAlarms = 0; + for (int i =0; i < alarmDescriptions.size(); ++i) { + Modbus_Point* alarmPoint = equipment->getModbus_Point(alarmDescriptions[i]); + if (alarmPoint) { + if (alarmPoint->getValue() == 1) numAlarms++; + } + } + if (numAlarms >= 1) equipment->setModbus_Point("General Alarm", 1); + else equipment->setModbus_Point("General Alarm", 0); } /** @@ -80,14 +92,4 @@ void updateFreeCooling(Equipment* equipment){ Modbus_Point* FreeCoolingValve = equipment->getModbus_Point("Free Cooling Valve"); FreeCoolingMode->setValue(FreeCoolingCommand->getValue()); FreeCoolingValve->setValue(FreeCoolingCommand->getValue()); - /** - if (FreeCoolingCommand->getValue() == 1) { - FreeCoolingMode->setValue(1); - FreeCoolingValve->setValue(1); - } - else { - FreeCoolingMode->setValue(0); - FreeCoolingValve->setValue(0); - } - */ } \ No newline at end of file diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp index 0991bb1..d3996c3 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp @@ -6,6 +6,7 @@ * * This file contains the implementation for the FailState, which defines * the behavior of the equipment when it has entered a fault condition. + * The unit enters Fail State if Sys 1 Fan Fault Alarm or Sys 2 Fan Fault Alarm is active. */ #include "ModbusPoints/Modbus_Point.h" #include "Equipment/Equipment.h" @@ -29,15 +30,31 @@ * @brief Constructs a new FailState object. * * This constructor receives a list of alarm descriptions and creates strategies - * to set the Compressor and Fan kW to 0. + * to set the unit back into an idle, de-energized state. * - * @param activeAlarms A vector of strings, where each string is the - * description of a Modbus point to be set as an active alarm. + * @param activeFaults A vector of strings, where each string is the + * description of the currently active faults. */ template<> -FailState::FailState(const std::vector& activeAlarms) { +FailState::FailState(const std::vector& activeFaults) { + addStrategy("Supply Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Return Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 1000)); + + addStrategy("System CHW Out", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("System CHW In", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 1000)); + addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 1000)); + addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 1000)); + addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 1000)); + addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); + addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); + addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); + addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); + addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 1000)); + addStrategy("VSD Output Frequency", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 1 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 2 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); @@ -48,33 +65,44 @@ FailState::FailState(const std::vector& activeAlarms) { * @brief Executes the fail state's logic for one update cycle. * * This method first updates all alarms states and Free Cooling Mode (for ease of testing). - * If all alarms have been cleared --> StandbyState. - * If alarms are still active, ensures the Chiller Start Command remains at 0. + * If all faults have been cleared --> StandbyState. + * If faults are still active, ensures the Chiller Start Command remains at 0. * * @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) { - // Update alarms states, Free Cooling mode, Freeze Protection Mode + // Update alarms states, Free Cooling mode updateAlarms(equipment); updateFreeCooling(equipment); - const std::vector alarmDescriptions = { - "Sys 1 Alarm", "Sys 2 Alarm", "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm", + const std::vector FaultDescriptions = { + "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm", }; - // If no alarms active --> send to StandbyState() - bool alarms_active = false; - for (const auto& desc : alarmDescriptions) { + // If no faults active --> send to StandbyState() + bool faults_active = false; + for (const auto& desc : FaultDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point->getValue() == 1) { - alarms_active = true; + faults_active = true; } } - if (!alarms_active) return new StandbyState(); + if (!faults_active) return new StandbyState(); setPointValue(equipment, "Chiller Start Command", 0); + + // Update Operational Code depending on Free Cooling Mode + int freeCoolingState = getPointValue(equipment, "Free Cooling Mode ON"); + if (freeCoolingState == 1){ + setPointValue(equipment, "Sys 1 Operational Code", 82); + setPointValue(equipment, "Sys 2 Operational Code", 82); + } + else{ + setPointValue(equipment, "Sys 1 Operational Code", 77); + setPointValue(equipment, "Sys 2 Operational Code", 77); + } _applyStrategies(equipment); return nullptr; diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp index b891f34..b476d17 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp @@ -60,11 +60,11 @@ RunningState::RunningState() { addStrategy("Sys 1 Run Hours", new TotalizerStrategy(1000)); addStrategy("Sys 2 Run Hours", new TotalizerStrategy(1000)); addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 1000)); + addStrategy("VSD Output Frequency", new SingleValueStrategy(59.0f, 1.0f, 1000)); addStrategy("Sys 1 Fan KW", new SingleValueStrategy(35.0f, 2.0f, 1000)); addStrategy("Sys 2 Fan KW", new SingleValueStrategy(23.0f, 2.0f, 1000)); addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(304.0f, 5.0f, 1000)); addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(198.0f, 5.0f, 1000)); - } /** @@ -88,23 +88,23 @@ State* RunningState::update(Equipment* equipmen updateAlarms(equipment); updateFreeCooling(equipment); - std::vector activeAlarmsDescriptions = {}; - const std::vector alarmDescriptions = { - "Sys 1 Alarm", "Sys 2 Alarm", "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm", + std::vector activeFaultDescriptions = {}; + const std::vector FaultDescriptions = { + "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm" }; - // Loop through alarms, create array of active alarms and send to FailState if any alarms are active - bool alarms_active = false; - for (const auto& desc : alarmDescriptions) { + // Loop through faults, create array of active faults and send to FailState if any faults are active + bool faults_active = false; + for (const auto& desc : FaultDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point->getValue() == 1) { - activeAlarmsDescriptions.push_back(desc); - alarms_active = true; + activeFaultDescriptions.push_back(desc); + faults_active = true; } } - if (alarms_active) return new FailState(activeAlarmsDescriptions); + if (faults_active) return new FailState(activeFaultDescriptions); - // If no alarms active and Start Command = 0--> send to StandbyState() + // If no faults active and Start Command = 0--> send to StandbyState() int Chiller_Enable = getPointValue(equipment, "Chiller Start Command"); // Modscan COIL 1 if (Chiller_Enable == 0){ return new StandbyState(); @@ -124,6 +124,17 @@ State* RunningState::update(Equipment* equipmen static_cast(CHW_In_strat)->setTarget(returnTemp); } + // Update Operational Code depending on Free Cooling Mode + int freeCoolingState = getPointValue(equipment, "Free Cooling Mode ON"); + if (freeCoolingState == 1){ + setPointValue(equipment, "Sys 1 Operational Code", 82); + setPointValue(equipment, "Sys 2 Operational Code", 82); + } + else{ + setPointValue(equipment, "Sys 1 Operational Code", 78); + setPointValue(equipment, "Sys 2 Operational Code", 78); + } + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp index 9448627..b5309ba 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp @@ -55,6 +55,7 @@ StandbyState::StandbyState() { addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 1000)); + addStrategy("VSD Output Frequency", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 1 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 2 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); @@ -82,7 +83,7 @@ State* StandbyState::update(Equipment* equipmen std::vector activeAlarmsDescriptions = {}; const std::vector alarmDescriptions = { - "Sys 1 Alarm", "Sys 2 Alarm", "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm", + "Sys 1 Fan Fault Alarm", "Sys 2 Fan Fault Alarm" }; // Loop through alarms, create array of active alarms and send to FailState if any alarms are active @@ -102,6 +103,17 @@ State* StandbyState::update(Equipment* equipmen return new RunningState(); } + // Update Operational Code depending on Free Cooling Mode + int freeCoolingState = getPointValue(equipment, "Free Cooling Mode ON"); + if (freeCoolingState == 1){ + setPointValue(equipment, "Sys 1 Operational Code", 82); + setPointValue(equipment, "Sys 2 Operational Code", 82); + } + else{ + setPointValue(equipment, "Sys 1 Operational Code", 77); + setPointValue(equipment, "Sys 2 Operational Code", 77); + } + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index 16eb93f..e240df1 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -55,58 +55,57 @@ modbusMap mb_map[] = { {COIL, 0, 0, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. - {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY - {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY - {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE - {COIL, 4, 0, "Sys 2 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE - {COIL, 5, 0, "Free Cooling Mode ON"}, // Use in Modscan - Used for Arduino simulation only - {COIL, 6, 0, "General Alarm ON"}, // Use in Modscan - Used for Arduino simulation only + {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) + {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) + {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) + {COIL, 4, 0, "Sys 2 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) + {COIL, 5, 0, "Free Cooling Mode ON"}, // Use in Modscan - Used for Arduino simulation only - {DI, 65, 0, "General Alarm"}, // part of Modbus map, but not included in code --> INDICATION ONLY + {DI, 65, 0, "General Alarm"}, // if any alarm is active, General Alarm = 1 --> used for INDICATION ONLY (assumption) {DI, 174, 0, "Sys 1 Fan Fault Alarm"}, {DI, 175, 0, "Sys 2 Fan Fault Alarm"}, {IR, 130, 0, "Free Cooling Mode"}, {IR, 165, 0, "Free Cooling Valve"}, - {HR, 0, 0, "Chiller Status"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {HR, 1, 0, "Chiller Temp Setpoint"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {HR, 2, 0, "Supply Temp"}, // Use in Modscan - Hard IO in SCP (PICS?), Used for Arduino simulation only - {HR, 3, 0, "Return Temp"}, // Use in Modscan - Hard IO in SCP (PICS?), Used for Arduino simulation only + {HR, 0, 0, "Chiller Status"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only + {HR, 1, 0, "Chiller Temp Setpoint"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only + {HR, 2, 0, "Supply Temp"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only + {HR, 3, 0, "Return Temp"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only {HR, 4, 70, "System CHW Out"}, {HR, 5, 70, "System CHW In"}, - {HR, 7, 0, "Sys 1 Condenser Temp"}, - {HR, 9, 0, "Ambient Temp"}, + {HR_10x, 7, 0, "Sys 1 Condenser Temp"}, + {HR_10x, 9, 0, "Ambient Temp"}, - {HR, 11, 0, "Sys 1 Oil Pressure"}, - {HR, 12, 0, "Sys 1 Suction Pressure"}, - {HR, 13, 0, "Sys 1 Discharge Pressure"}, - {HR, 14, 0, "Sys 1 Compressor Pct FLA"}, - {HR, 15, 0, "Sys 1 Run Hours"}, - {HR, 16, 0, "Sys 1 Starts"}, + {HR_10x, 11, 0, "Sys 1 Oil Pressure"}, + {HR_10x, 12, 0, "Sys 1 Suction Pressure"}, + {HR_10x, 13, 0, "Sys 1 Discharge Pressure"}, + {HR_10x, 14, 0, "Sys 1 Compressor Pct FLA"}, + {HR, 15, 0, "Sys 1 Run Hours"}, + {HR, 16, 0, "Sys 1 Starts"}, - {HR, 20, 0, "Sys 2 Oil Pressure"}, - {HR, 21, 0, "Sys 2 Suction Pressure"}, - {HR, 22, 0, "Sys 2 Discharge Pressure"}, - {HR, 23, 0, "Sys 2 Compressor Pct FLA"}, - {HR, 24, 0, "Sys 2 Run Hours"}, - {HR, 25, 0, "Sys 2 Starts"}, + {HR_10x, 20, 0, "Sys 2 Oil Pressure"}, + {HR_10x, 21, 0, "Sys 2 Suction Pressure"}, + {HR_10x, 22, 0, "Sys 2 Discharge Pressure"}, + {HR_10x, 23, 0, "Sys 2 Compressor Pct FLA"}, + {HR, 24, 0, "Sys 2 Run Hours"}, + {HR, 25, 0, "Sys 2 Starts"}, - {HR, 26, 0, "VSD Output Frequency"}, // part of Modbus map, but not included in code + {HR_10x, 26, 0, "VSD Output Frequency"}, // part of Modbus map, but not included in code - {HR, 29, 77, "Sys 1 Operational Code"}, - {HR, 30, 0, "Sys 1 Fault Code"}, - {HR, 31, 77, "Sys 2 Operational Code"}, - {HR, 32, 0, "Sys 2 Fault Code"}, + {HR, 29, 77, "Sys 1 Operational Code"}, // 77:not running, 78:running, 82:free cooling + {HR, 30, 0, "Sys 1 Fault Code"}, // 56:condenser fan VSD warning + {HR, 31, 77, "Sys 2 Operational Code"}, // 77:not running, 78:running, 82:free cooling + {HR, 32, 0, "Sys 2 Fault Code"}, // 56:condenser fan VSD warning - {HR, 39, 0, "Local Leaving Temp Setpoint"}, + {HR, 39, 0, "Local Leaving Temp Setpoint"}, - {HR, 49, 0, "Sys 2 Condenser Temp"}, - {HR, 140, 0, "Sys 1 Fan KW"}, - {HR, 141, 0, "Sys 1 Compressor KW"}, - {HR, 142, 0, "Sys 2 Fan KW"}, - {HR, 143, 0, "Sys 2 Compressor KW"}, + {HR_10x, 49, 0, "Sys 2 Condenser Temp"}, + {HR_10x, 140, 0, "Sys 1 Fan KW"}, + {HR_10x, 141, 0, "Sys 1 Compressor KW"}, + {HR_10x, 142, 0, "Sys 2 Fan KW"}, + {HR_10x, 143, 0, "Sys 2 Compressor KW"}, }; //Size of modbus map used in FOR cycles, automatically calculated. From 283625701538289ab929f55a8deb6d7f79691e10 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 31 Oct 2025 10:56:43 -0700 Subject: [PATCH 13/51] 10x registers Modified to 10x registers: Supply Temp, Return Temp, Return Humidity. Changed Supply and Return Temp in RunningState for PID strategy to work. --- .../State_Running.cpp | 14 ++++++++++++++ .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 18 +++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp index d0ce726..33c87c7 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp @@ -89,6 +89,20 @@ State* RunningState::update(Equipment* equipment) return new StandbyState(); } + // Due to 10x scaling of Supply and Return Air Temps, need to adjust for PID strategies + float returnTemp = getPointValue(equipment, "Return Air Temp")/10; + float supplyTemp = getPointValue(equipment, "Supply Air Temp")/10; + float returnTempSP = getPointValue(equipment, "Return Air Temp Setpoint"); + float supplyTempSP = getPointValue(equipment, "Supply Air Temp Setpoint"); + + Strategy_Behavior* FluidControlValve1_strat = getStrategy("Fluid Control Valve Position 1"); + Strategy_Behavior* FluidControlValve2_strat = getStrategy("Fluid Control Valve Position 2"); + Strategy_Behavior* FanSpeed_strat = getStrategy("Fan Speed"); + static_cast(FluidControlValve1_strat)->setLimits(supplyTempSP, supplyTemp); + static_cast(FluidControlValve2_strat)->setLimits(supplyTempSP, supplyTemp); + static_cast(FanSpeed_strat)->setLimits(returnTempSP, returnTemp); + + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index f1040fb..f547b18 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -136,16 +136,16 @@ modbusMap mb_map[] = {DI, 741, 0, "Alarm Compressor 2B Overload"}, {IR, 99, 0, "Unit Status"}, // 0:off, 1:on, 2:standby - {IR, 102, 0, "Fan Speed"}, - {IR, 129, 0, "Return Humidity"}, - {IR, 742, 0, "Return Air Temp"}, - {IR, 743, 0, "Supply Air Temp"}, - {IR, 1465, 0, "Supply Air Flow"}, - {IR, 2050, 0, "Fluid Control Valve Position 1"}, - {IR, 2051, 0, "Fluid Control Valve Position 2"}, + {IR, 102, 0, "Fan Speed"}, + {IR_10x, 129, 0, "Return Humidity"}, + {IR_10x, 742, 0, "Return Air Temp"}, + {IR_10x, 743, 0, "Supply Air Temp"}, + {IR, 1465, 0, "Supply Air Flow"}, + {IR, 2050, 0, "Fluid Control Valve Position 1"}, + {IR, 2051, 0, "Fluid Control Valve Position 2"}, - {HR, 732, 73, "Supply Air Temp Setpoint"}, - {HR, 753, 80, "Return Air Temp Setpoint"}, + {HR, 732, 73, "Supply Air Temp Setpoint"}, + {HR, 753, 80, "Return Air Temp Setpoint"}, }; //Size of modbus map used in FOR cycles, automatically calculated. From 94dbd4c5c00d4b569b098e0ceaeaa03d5549f2c3 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 31 Oct 2025 11:08:48 -0700 Subject: [PATCH 14/51] minor adjustments --- src/BMS/CHILLER/CH_York_YVAA_RTU/README.md | 2 +- src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 2 +- src/BMS/CHILLER/CH_York_YVAA_RTU/main.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md b/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md index 83edb97..f2bc7c7 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/README.md @@ -20,7 +20,7 @@ The code is written for an ESP8266/ESP32-style microcontroller with WiFi capabil --- ## States and Strategies -Updates Alarms States. Only the Sys 1 Fan Fault or Sys 2 Fan Fault will end unit --> FailState +Updates Alarms States. Only the Sys 1 Fan Fault or Sys 2 Fan Fault will send unit --> FailState Sys 1 Alarm, Sys 2 Alarm, and General Alarm will annunciate only, will not stop the unit (this is an assumption the program follows, may differ in field). Updates Free Cooling Mode: Free Cooling Mode is activated using a coil, for simulation purposes only. Modbus points are simulated, mostly with a SingleValue strategy for image verification in Ignition. diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index e240df1..79e7383 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -92,7 +92,7 @@ modbusMap mb_map[] = {HR, 24, 0, "Sys 2 Run Hours"}, {HR, 25, 0, "Sys 2 Starts"}, - {HR_10x, 26, 0, "VSD Output Frequency"}, // part of Modbus map, but not included in code + {HR_10x, 26, 0, "VSD Output Frequency"}, {HR, 29, 77, "Sys 1 Operational Code"}, // 77:not running, 78:running, 82:free cooling {HR, 30, 0, "Sys 1 Fault Code"}, // 56:condenser fan VSD warning diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/main.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/main.cpp index 5dbc9f1..ec953c3 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/main.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/main.cpp @@ -1,11 +1,11 @@ /** * @file main.cpp - * @brief Main execution program for the Daikin Chiller (RTU) Emulator. - * @author Emmanuel Hernandez Cruz + * @brief Main execution program for the York YVAA Chiller (RTU) Emulator. + * @author Emmanuel Hernandez Cruz, Robert J. Davis * @date 2025-09-02 * * @details This file contains the main execution program for an Arduino-based - * emulator of a Daikin Chiller unit. The program communicates via the + * emulator of a York YVAA Chiller unit. The program communicates via the * Modbus RTU protocol over a serial connection. * * The setup() function initializes the following: From e04196dd111f012674bc651467eeb63bac6ceadc Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 31 Oct 2025 15:07:43 -0700 Subject: [PATCH 15/51] minor adjustments --- src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp | 3 ++- src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp | 3 ++- src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h | 2 +- src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp | 6 +++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp index 14992cc..d9910a0 100644 --- a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Fail.cpp @@ -33,7 +33,8 @@ */ template<> FailState::FailState(const std::vector& activeAlarms) { - addStrategy("Duct RH", new SingleValueStrategy(35.0f, 5.0f, 1000)); + addStrategy("Duct RH", new SingleValueStrategy(35.0f, 5.0f, 1000)); + addStrategy("Tank Temp", new SingleValueStrategy(80.0f, 1.0f, 3000)); } /** diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp index f975167..d47cd2d 100644 --- a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/State_Standby.cpp @@ -37,7 +37,8 @@ */ template<> StandbyState::StandbyState() { - addStrategy("Duct RH", new SingleValueStrategy(35.0f, 5.0f, 1000)); + addStrategy("Duct RH", new SingleValueStrategy(35.0f, 5.0f, 1000)); + addStrategy("Tank Temp", new SingleValueStrategy(80.0f, 1.0f, 3000)); } /** diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h index b245e29..41b252c 100644 --- a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h @@ -79,7 +79,7 @@ modbusMap mb_map[] = {DI, 8, 0, "Drain Valve"}, // 0:not draining, 1:draining {DI, 9, 0, "Alarms Present"}, // Used for Modscan testing only - not part of vendor Modbus table - {IR, 0, 0, "Space RH"}, // Relative_Humidity + {IR, 0, 0, "Space RH"}, // Relative_Humidity --> NOT USED, sensor not connected to HUM {IR, 2, 0, "Duct RH"}, // OSet_CV {IR, 3, 0, "Steam Demand Mass"}, {IR, 4, 0, "Steam Demand Percent"}, diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp index 286a98c..a38c2d0 100644 --- a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/main.cpp @@ -1,10 +1,10 @@ /** * @file main.cpp - * @brief Main execution program for the CRAH Unit (TCP) Emulator. - * @author Emmanuel Hernandez Cruz + * @brief Main execution program for the DriSteem Humidifier (TCP) Emulator. + * @author Emmanuel Hernandez Cruz, Robert J Davis * @date 2025-09-02 * - * @details This file contains the main execution program for an Arduino-based emulator of a CRAH unit. + * @details This file contains the main execution program for an Arduino-based emulator of the DriSteem Humidifier unit. * The program uses a Wi-Fi connection to communicate via the Modbus IP protocol. * * The setup() function initializes the following: From 40282fca0d8ff3d107a5303a376c0a3abd65855d Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 4 Nov 2025 14:16:03 -0700 Subject: [PATCH 16/51] updates for Schertz testing --- platformio.ini | 11 ++++- src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 10 ++--- src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 3 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 4 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 2 +- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 13 +++--- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 9 ++-- .../HUM/HUM_DriSteem_RTS_RX36_TCP/config.h | 8 ++-- .../PHX3_VFD_ABB_ACH580_RTU/State_Fail.cpp | 11 +++-- .../PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp | 31 +++++--------- .../PHX3_VFD_ABB_ACH580_RTU/State_Standby.cpp | 11 +++-- src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h | 42 +++++++++++-------- 12 files changed, 85 insertions(+), 70 deletions(-) diff --git a/platformio.ini b/platformio.ini index 2bec804..ce2f5ec 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,10 +10,10 @@ [platformio] -default_envs = PHX3_CRAH_LIEBERT_80_SLAB_TCP ; Select here the name of the configuration you want to download +default_envs = PHX3_VFD_ABB_ACH580_RTU ; Select here the name of the configuration you want to download [env] -upload_port = COM9 +upload_port = COM13 [common_env_options] framework = arduino @@ -226,3 +226,10 @@ board = dfrobot_firebeetle2_esp32e extends = common_env_options build_flags = -D USE_MODBUS_IP build_src_filter = -<*> + + +[env:CRAH_UMAS_TCP] +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/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index 79e7383..ee3284c 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -22,11 +22,11 @@ * @{ */ #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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 35); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ + IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; #else diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index eafcf6b..c2f9171 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -16,6 +16,7 @@ #include "Strategies/Strategy_Ramp.h" #include "Strategies/Strategy_SingleValue.h" #include "Strategies/Strategy_PID.h" +#include "Strategies/Strategy_Saw.h" #include "States/State_Standby.h" #include "States/State_Running.h" #include "States/State_Fail.h" @@ -57,7 +58,7 @@ FailState::FailState(const std::vector& activeAlarms) { addStrategy("Amps Fan 7", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 8", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 9", new RampStrategy(0.0f, 4.5f, 1000)); - + addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); } /** diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index f85524b..00cab5f 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -71,11 +71,11 @@ RunningState::RunningState() { addStrategy("Operating Hours Fan 7", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 8", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 9", new TotalizerStrategy(1000)); - addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.0f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan + addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.2f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan addStrategy("Return Air Temp", new SawStrategy(70.0f, 80.0f, 1.0f, 1000)); addStrategy("Filter Differential Pressure", new SawStrategy(0.0f, 5.0f, 0.2f, 1000)); addStrategy("CW Valve Position", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); // SAT must be greater than SAT Setpoint for this PID to work. - + addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); } /** diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index 70be6d4..a0f6b7d 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -61,7 +61,7 @@ StandbyState::StandbyState() { addStrategy("Amps Fan 7", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 8", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 9", new RampStrategy(0.0f, 4.5f, 1000)); - + addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); } /** diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 9490535..fc381ad 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ - const char *password = "52761492"; /**< @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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 30, 22, 100); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -135,7 +135,8 @@ modbusMap mb_map[] = {IR_FLOAT, 73, 0, "Amps Fan 6"}, {IR_FLOAT, 75, 0, "Amps Fan 7"}, {IR_FLOAT, 77, 0, "Amps Fan 8"}, - {IR_FLOAT, 79, 0, "Amps Fan 9"}, + {IR_FLOAT, 79, 0, "Amps Fan 9"}, + {IR_FLOAT, 99, 0, "CRAH Heartbeat"}, // Placeholder - we don't have this from UMAS yet. Not used in logic yet. {HR_FLOAT, 13, 0, "Fan Speed Setpoint"}, // Receive signal from PLC {HR_FLOAT, 17, 0, "Supply Air Temp Setpoint"}, // Receive signal from PLC @@ -143,7 +144,7 @@ modbusMap mb_map[] = {HR_FLOAT, 23, 0, "Fan Max Speed"}, // Send to PLC {HR, 25, 0, "BMS Control Source"}, // Receive signal from PLC 0:Speed, 1:Room Temp {HR, 26, 2, "BMS Enable Source"}, // Receive signal from PLC 0:Keypad, 1:DI, 2:BMS - {HR, 99, 0, "CRAH Heartbeat"} // Placeholder - we don't have this from UMAS yet. Not used in logic yet. + }; //Size of modbus map used in FOR cycles, automatically calculated. diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index f547b18..c027708 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -20,11 +20,10 @@ * @brief Parameters for Modbus TCP communication. * @{ */ - #include - const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ - const char *password = "52761492"; /**< @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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 63); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h index 41b252c..a40b037 100644 --- a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ - const char *password = "52761492"; /**< @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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 67); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Fail.cpp b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Fail.cpp index f7b8919..987b5fd 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Fail.cpp +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Fail.cpp @@ -32,9 +32,7 @@ */ template<> FailState::FailState(const std::vector& activeAlarms) { - addStrategy("Motor Speed Used", new RampStrategy(0.0f, 200.0f, 1000 )); addStrategy("Speed Feedback", new RampStrategy(0.0f, 200.0f, 1000 )); - addStrategy("Motor Speed estimated", new RampStrategy(0.0f, 200.0f, 1000 )); addStrategy("Motor Current", new RampStrategy(0.0f, 20.0f, 1000 )); addStrategy("Motor Torque", new RampStrategy(0.0f, 20.0f, 1000 )); addStrategy("Inverter Temperature", new RampStrategy(0.0f, 1.0f, 1000 )); @@ -42,7 +40,7 @@ FailState::FailState(const std::vector& activeAlarms) { addStrategy("Output Frequency", new SingleValueStrategy(0.1f, 0.2f, 1000 )); addStrategy("Output Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 )); addStrategy("DC Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 )); - addStrategy("Output Power", new SingleValueStrategy(0.1f, 0.1f, 1000 )); + addStrategy("Motor Shaft Power", new SingleValueStrategy(0.1f, 0.1f, 1000 )); } /** @@ -77,6 +75,13 @@ template<> void FailState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Fail State..."); + setPointValue(equipment, "Speed Scaling", 1800); + setPointValue(equipment, "Frequency Scaling", 60); + setPointValue(equipment, "Nominal Current", 65); + setPointValue(equipment, "Nominal Voltage", 480); + setPointValue(equipment, "Nominal Frequency", 60); + setPointValue(equipment, "Nominal Speed", 1800); + setPointValue(equipment, "Nominal Power", 50); setPointValue(equipment, "Run Status", 0); } diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp index 36d586d..5748056 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp @@ -41,9 +41,7 @@ */ template<> RunningState::RunningState() { - addStrategy("Motor Speed Used", new RampStrategy(1800.0f, 100.0f, 1000)); addStrategy("Speed Feedback", new RampStrategy(1800.0f, 100.0f, 1000)); - addStrategy("Motor Speed estimated", new RampStrategy(1800.0f, 100.0f, 1000)); addStrategy("Motor Current", new RampStrategy(65.0f, 7.0f, 1000)); addStrategy("Motor Torque", new RampStrategy(90.0f, 10.0f, 1000)); addStrategy("Inverter Temperature", new SquareStrategy(40.0f, 80.0f, 1000)); @@ -51,9 +49,9 @@ RunningState::RunningState() { addStrategy("Output Frequency", new RampStrategy(60.0f, 3.0f, 1000 )); addStrategy("Output Voltage", new RampStrategy(480.0f, 15.0f, 1000 )); addStrategy("DC Voltage", new RampStrategy(678.0f, 20.0f, 1000 )); - addStrategy("Output Power", new RampStrategy(36.7f, 2.0f, 1000 )); - addStrategy("Inverter kWh cnt", new TotalizerStrategy(1000)); - addStrategy("Hours Run", new TotalizerStrategy(1000)); + addStrategy("Motor Shaft Power", new RampStrategy(36.7f, 2.0f, 1000 )); + addStrategy("Inverter MWh counter", new TotalizerStrategy(1000)); + addStrategy("Inverter kWh counter", new TotalizerStrategy(1000)); } /** @@ -94,25 +92,11 @@ State* RunningState::update(Equipment* equipmen float power_update = speed_pct * speed_pct * speed_pct * 36.77f; // 50 hp ~ 36.77kW float currentSP = getPointValue(equipment, "Speed Cmd"); - Strategy_Behavior* motorSpeedUsed = getStrategy("Motor Speed Used"); - // 2. Check if the strategy exists - if (motorSpeedUsed) { - // 3. Cast it to a RampStrategy pointer and call setSetpoint. - static_cast(motorSpeedUsed)->setTarget(currentSP); - } - Strategy_Behavior* speedFeedback = getStrategy("Speed Feedback"); if (speedFeedback) { static_cast(speedFeedback)->setTarget(currentSP); } - // To have Motor Speed estimated slightly different - for purposes of differentiating in Ignition - float rpm_est = currentSP * 0.98f; - Strategy_Behavior* motorSpeedEst = getStrategy("Motor Speed estimated"); - if (motorSpeedEst) { - static_cast(motorSpeedEst)->setTarget(rpm_est); - } - Strategy_Behavior* frequencystrategy = getStrategy("Output Frequency"); if (frequencystrategy) { static_cast(frequencystrategy)->setTarget(freq_update); @@ -138,7 +122,7 @@ State* RunningState::update(Equipment* equipmen static_cast(voltagestrategy)->setTarget(voltage_update); } - Strategy_Behavior* powerstrategy = getStrategy("Output Power"); + Strategy_Behavior* powerstrategy = getStrategy("Motor Shaft Power"); if (powerstrategy) { static_cast(powerstrategy)->setTarget(power_update); } @@ -157,6 +141,13 @@ template<> void RunningState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Running State..."); + setPointValue(equipment, "Speed Scaling", 1800); + setPointValue(equipment, "Frequency Scaling", 60); + setPointValue(equipment, "Nominal Current", 65); + setPointValue(equipment, "Nominal Voltage", 480); + setPointValue(equipment, "Nominal Frequency", 60); + setPointValue(equipment, "Nominal Speed", 1800); + setPointValue(equipment, "Nominal Power", 50); setPointValue(equipment, "Run Status", 1); } diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Standby.cpp b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Standby.cpp index 01629e0..41b3048 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Standby.cpp +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Standby.cpp @@ -30,9 +30,7 @@ */ template<> StandbyState::StandbyState() { - addStrategy("Motor Speed Used", new RampStrategy(0.0f, 200.0f, 1000 )); addStrategy("Speed Feedback", new RampStrategy(0.0f, 200.0f, 1000 )); - addStrategy("Motor Speed estimated", new RampStrategy(0.0f, 200.0f, 1000 )); addStrategy("Motor Current", new RampStrategy(0.0f, 20.0f, 1000 )); addStrategy("Motor Torque", new RampStrategy(0.0f, 20.0f, 1000 )); addStrategy("Inverter Temperature", new RampStrategy(0.0f, 1.0f, 1000 )); @@ -40,7 +38,7 @@ StandbyState::StandbyState() { addStrategy("Output Frequency", new SingleValueStrategy(0.1f, 0.2f, 1000 )); addStrategy("Output Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 )); addStrategy("DC Voltage", new SingleValueStrategy(0.1f, 0.1f, 1000 )); - addStrategy("Output Power", new SingleValueStrategy(0.1f, 0.1f, 1000 )); + addStrategy("Motor Shaft Power", new SingleValueStrategy(0.1f, 0.1f, 1000 )); } /** @@ -84,6 +82,13 @@ template<> void StandbyState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Standby State..."); + setPointValue(equipment, "Speed Scaling", 1800); + setPointValue(equipment, "Frequency Scaling", 60); + setPointValue(equipment, "Nominal Current", 65); + setPointValue(equipment, "Nominal Voltage", 480); + setPointValue(equipment, "Nominal Frequency", 60); + setPointValue(equipment, "Nominal Speed", 1800); + setPointValue(equipment, "Nominal Power", 50); setPointValue(equipment, "Run Status", 0); } diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h index 1389e79..e347759 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h @@ -63,25 +63,31 @@ modbusMap mb_map[] = {HR, 155, 1, "Fault Status"}, // arbitrary register number - 0:faulted, 1:not faulted (simulated hardwire IO). When = 0, will turn off VFD. {HR, 156, 0, "Speed Feedback"}, // arbitrary register number - send signal to PLC (simulated hardwire IO). Will be equal to Motor Speed Used register - {HR_FLOAT, 20201, 0, "Motor Speed Used"}, // RJD: 1800 rpm max - {HR_FLOAT, 20203, 0, "Motor Speed estimated"}, // RJD: 1800 rpm max - {HR_FLOAT, 20211, 0, "Output Frequency"}, // 60 Hz @100% speed - {HR_FLOAT, 20213, 0, "Motor Current"}, // RJD: Changed from HR_10x to HR, 65 FLA - {HR_FLOAT, 20219, 0, "Motor Torque"}, // % of nominal torque - {HR_FLOAT, 20221, 0, "DC Voltage"}, // approx 678 VDC @100% speed - {HR_FLOAT, 20225, 0, "Output Voltage"}, // RJD: 480 VAC - {HR_FLOAT, 20227, 0, "Output Power"}, //max 372580 // RJD: Changed from HR_10x to HR, 50 hp ~ 36.77 kW - {HR_FLOAT, 20239, 0, "Inverter kWh cnt"}, - {HR_FLOAT, 21005, 0, "Hours Run"}, - {HR_FLOAT, 21021, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit + {HR_FLOAT, 100, 0, "Motor Speed Used"}, // 1800 rpm max + {HR_FLOAT, 105, 0, "Output Frequency"}, // 60 Hz @100% speed + {HR_FLOAT, 106, 0, "Motor Current"}, // 65 FLA + {HR_FLOAT, 109, 0, "Motor Torque"}, // % of nominal torque + {HR_FLOAT, 110, 0, "DC Voltage"}, // approx 678 VDC @100% speed + {HR_FLOAT, 112, 0, "Output Voltage"}, // 480 VAC + {HR_FLOAT, 116, 0, "Motor Shaft Power"}, // 50 hp ~ 36.77 kW + {HR_FLOAT, 118, 0, "Inverter MWh counter"}, + {HR_FLOAT, 119, 0, "Inverter kWh counter"}, + {HR_FLOAT, 510, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit + {HR, 519, 0, "Diagnostic Word"}, // not used in program. Bit 9:Drive Over-Temp Alarm - {HR, 21243, 0, "HOA Status Word"}, // not used in program - {HR, 20801, 0, "Trip Fault"}, // not used in program - {HR, 20821, 0, "Last Fault"}, // not used in program - {HR, 20823, 0, "2nd to last Fault"}, // not used in program - {HR, 20825, 0, "3rd to last Fault"}, // not used in program - {HR, 21221, 0, "Main Status Word"}, // not used in program - {HR, 21231, 0, "Drive Status Word 1"}, // not used in program + {HR, 1000, 0, "DI Status"}, // not used in program. + {HR, 1211, 0, "AI1 Scaled"}, // not used in program. + {HR, 1221, 0, "AI2 Scaled"}, // not used in program. + {HR, 1310, 0, "AO1 Actual"}, // not used in program. + {HR, 1910, 0, "External Control Location"}, // not used in program. + {HR_FLOAT, 4600, 0, "Speed Scaling"}, // ADD: 1800 rpm + {HR_FLOAT, 4601, 0, "Frequency Scaling"}, // ADD: 60 Hz + {HR_FLOAT, 9905, 0, "Nominal Current"}, // ADD: 65 A + {HR_FLOAT, 9906, 0, "Nominal Voltage"}, // ADD: 480 V + {HR_FLOAT, 9907, 0, "Nominal Frequency"}, // ADD: 60 Hz + {HR_FLOAT, 9908, 0, "Nominal Speed"}, // ADD: 1800 rpm + {HR_FLOAT, 9909, 0, "Nominal Power"}, // ADD: 50 hp + }; //Size of modbus map used in FOR cycles, automatically calculated. /** From f0e3a3a5e568fade229c94642f33c99e5928199d Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 4 Nov 2025 14:21:19 -0700 Subject: [PATCH 17/51] change com port during testing --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index ce2f5ec..9b4bf2c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ default_envs = PHX3_VFD_ABB_ACH580_RTU ; Select here the name of the configuration you want to download [env] -upload_port = COM13 +upload_port = COM6 [common_env_options] framework = arduino From dfc103f1e1719835de4e94e6b432fc75a10f9d85 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 4 Nov 2025 15:15:45 -0700 Subject: [PATCH 18/51] updated PHX3 VFD registers per new UDT --- .../PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp | 3 +- src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h | 48 +++++++++---------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp index 5748056..9fc5ab2 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/State_Running.cpp @@ -90,8 +90,9 @@ State* RunningState::update(Equipment* equipmen float torque_update = speed_pct * speed_pct * 100; // This is a % of nominal motor torque float freq_update = speed_pct * 60; float power_update = speed_pct * speed_pct * speed_pct * 36.77f; // 50 hp ~ 36.77kW - + float currentSP = getPointValue(equipment, "Speed Cmd"); + Strategy_Behavior* speedFeedback = getStrategy("Speed Feedback"); if (speedFeedback) { static_cast(speedFeedback)->setTarget(currentSP); diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h index e347759..d3c2a9e 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h @@ -61,32 +61,32 @@ modbusMap mb_map[] = {HR, 152, 0, "HOA Command"}, // arbitrary register number - not used in program {HR, 154, 0, "Run Status"}, // arbitrary register number - 0:off, 1:on (simulated hardwire IO) sending feedback to PLC during simulation. {HR, 155, 1, "Fault Status"}, // arbitrary register number - 0:faulted, 1:not faulted (simulated hardwire IO). When = 0, will turn off VFD. - {HR, 156, 0, "Speed Feedback"}, // arbitrary register number - send signal to PLC (simulated hardwire IO). Will be equal to Motor Speed Used register + // {HR, 156, 0, "Speed Feedback"}, // arbitrary register number - send signal to PLC (simulated hardwire IO). Will be equal to Motor Speed Used register - {HR_FLOAT, 100, 0, "Motor Speed Used"}, // 1800 rpm max - {HR_FLOAT, 105, 0, "Output Frequency"}, // 60 Hz @100% speed - {HR_FLOAT, 106, 0, "Motor Current"}, // 65 FLA - {HR_FLOAT, 109, 0, "Motor Torque"}, // % of nominal torque - {HR_FLOAT, 110, 0, "DC Voltage"}, // approx 678 VDC @100% speed - {HR_FLOAT, 112, 0, "Output Voltage"}, // 480 VAC - {HR_FLOAT, 116, 0, "Motor Shaft Power"}, // 50 hp ~ 36.77 kW - {HR_FLOAT, 118, 0, "Inverter MWh counter"}, - {HR_FLOAT, 119, 0, "Inverter kWh counter"}, - {HR_FLOAT, 510, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit - {HR, 519, 0, "Diagnostic Word"}, // not used in program. Bit 9:Drive Over-Temp Alarm + {HR, 100, 0, "Speed Feedback"}, // 1800 rpm max + {HR, 105, 0, "Output Frequency"}, // 60 Hz @100% speed + {HR, 106, 0, "Motor Current"}, // 65 FLA + {HR, 109, 0, "Motor Torque"}, // % of nominal torque + {HR, 110, 0, "DC Voltage"}, // approx 678 VDC @100% speed + {HR, 112, 0, "Output Voltage"}, // 480 VAC + {HR, 116, 0, "Motor Shaft Power"}, // 50 hp ~ 36.77 kW + {HR, 118, 0, "Inverter MWh counter"}, + {HR, 119, 0, "Inverter kWh counter"}, + {HR, 510, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit + {HR, 519, 0, "Diagnostic Word"}, // not used in program. Bit 9:Drive Over-Temp Alarm - {HR, 1000, 0, "DI Status"}, // not used in program. - {HR, 1211, 0, "AI1 Scaled"}, // not used in program. - {HR, 1221, 0, "AI2 Scaled"}, // not used in program. - {HR, 1310, 0, "AO1 Actual"}, // not used in program. - {HR, 1910, 0, "External Control Location"}, // not used in program. - {HR_FLOAT, 4600, 0, "Speed Scaling"}, // ADD: 1800 rpm - {HR_FLOAT, 4601, 0, "Frequency Scaling"}, // ADD: 60 Hz - {HR_FLOAT, 9905, 0, "Nominal Current"}, // ADD: 65 A - {HR_FLOAT, 9906, 0, "Nominal Voltage"}, // ADD: 480 V - {HR_FLOAT, 9907, 0, "Nominal Frequency"}, // ADD: 60 Hz - {HR_FLOAT, 9908, 0, "Nominal Speed"}, // ADD: 1800 rpm - {HR_FLOAT, 9909, 0, "Nominal Power"}, // ADD: 50 hp + {HR, 1000, 0, "DI Status"}, // not used in program. + {HR, 1211, 0, "AI1 Scaled"}, // not used in program. + {HR, 1221, 0, "AI2 Scaled"}, // not used in program. + {HR, 1310, 0, "AO1 Actual"}, // not used in program. + {HR, 1910, 0, "External Control Location"}, // not used in program. + {HR, 4600, 0, "Speed Scaling"}, // ADD: 1800 rpm + {HR, 4601, 0, "Frequency Scaling"}, // ADD: 60 Hz + {HR, 9905, 0, "Nominal Current"}, // ADD: 65 A + {HR, 9906, 0, "Nominal Voltage"}, // ADD: 480 V + {HR, 9907, 0, "Nominal Frequency"}, // ADD: 60 Hz + {HR, 9908, 0, "Nominal Speed"}, // ADD: 1800 rpm + {HR, 9909, 0, "Nominal Power"}, // ADD: 50 hp }; //Size of modbus map used in FOR cycles, automatically calculated. From e5ae233875e4e5538be1414686af04e70d2246e4 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Wed, 5 Nov 2025 07:13:59 -0700 Subject: [PATCH 19/51] Added Fan Speed Feedback register to UMAS DH CRAH. Added Fan Speed Feedback register to UMAS DH CRAH. --- platformio.ini | 2 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 2 ++ src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 9b4bf2c..b7351a8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,7 @@ [platformio] -default_envs = PHX3_VFD_ABB_ACH580_RTU ; Select here the name of the configuration you want to download +default_envs = CRAH_UMAS_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM6 diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index 00cab5f..ef8177c 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -141,6 +141,8 @@ State* RunningState::update(Equipment* equipment) } } + setPointValue(equipment, "Fan Speed Feedback", BMS_Speed_Setpoint); + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index fc381ad..196db82 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 30, 22, 100); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 49); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -144,6 +144,7 @@ modbusMap mb_map[] = {HR_FLOAT, 23, 0, "Fan Max Speed"}, // Send to PLC {HR, 25, 0, "BMS Control Source"}, // Receive signal from PLC 0:Speed, 1:Room Temp {HR, 26, 2, "BMS Enable Source"}, // Receive signal from PLC 0:Keypad, 1:DI, 2:BMS + {HR_FLOAT, 28, 0, "Fan Speed Feedback"}, }; From b4a626b908749a75a9ab645e27b7ae1e8b6455b8 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Thu, 6 Nov 2025 06:52:10 -0700 Subject: [PATCH 20/51] minor adjustments to CRAH UMAS TCP added Fan Speed Feedback register 40029, initialized unit to run for better image visualization while we wait for PICS-Arduino solution. --- platformio.ini | 4 +-- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 27 +++++++++++++++++-- src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 3 +++ src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 10 +++++-- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 5 ++-- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 6 ++--- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 2 +- .../HUM/HUM_DriSteem_RTS_RX36_TCP/config.h | 2 +- src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h | 4 +-- 9 files changed, 48 insertions(+), 15 deletions(-) diff --git a/platformio.ini b/platformio.ini index b7351a8..efbda27 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,10 +10,10 @@ [platformio] -default_envs = CRAH_UMAS_TCP ; Select here the name of the configuration you want to download +default_envs = CH_York_YVAA_RTU ; Select here the name of the configuration you want to download [env] -upload_port = COM6 +upload_port = COM16 [common_env_options] framework = arduino diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index 056bf7b..f980695 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -112,7 +112,6 @@ void updateAnalogs(Equipment* equipment){ else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Temp", 104.0f); } - else equipment->setModbus_Point("Return Air Temp", 74.0f); if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Humidity", 15.0f); @@ -120,5 +119,29 @@ void updateAnalogs(Equipment* equipment){ else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Humidity", 65.0f); } - else equipment->setModbus_Point("Return Air Humidity", 35.0f); +} + +/** + * @brief This function is used to update the Control Mode (feedback), + * based on the selected BMS Control Source and BMS Enable Source. + * + * This is a function used in the update() of the Standby, Running, and Fail States. + * +*/ +void checkHB(Equipment* equipment){ + Modbus_Point* PLC_Heartbeat = equipment -> getModbus_Point ("PLC Heartbeat"); + int BMS_Control_Source = BMS_Control_Source_Pt ? BMS_Control_Source_Pt->getValue() : 0; + int BMS_Enable_Source = BMS_Enable_Source_Pt ? BMS_Enable_Source_Pt->getValue() : 0; + int Control_Mode_Selected = Control_Mode_Pt ? Control_Mode_Pt->getValue() : -1; + + if (BMS_Control_Source == 0 && BMS_Enable_Source == 2) { + Control_Mode_Selected = 0; + } else if (BMS_Control_Source == 1 && BMS_Enable_Source == 2) { + Control_Mode_Selected = 1; + } else if (BMS_Enable_Source == 0) { + Control_Mode_Selected = 2; + } + equipment->setModbus_Point("Control Mode Selected", Control_Mode_Selected); + + equipment->setModbus_Point("General Alarm", 0); } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index c2f9171..eed9417 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -40,6 +40,9 @@ FailState::FailState(const std::vector& activeAlarms) { // Fan speed --> 0, Run Status --> 0, Amps --> 0 addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); + addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); + addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 10.0f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index ef8177c..a7b797b 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -72,10 +72,12 @@ RunningState::RunningState() { addStrategy("Operating Hours Fan 8", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 9", new TotalizerStrategy(1000)); addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.2f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan - addStrategy("Return Air Temp", new SawStrategy(70.0f, 80.0f, 1.0f, 1000)); + addStrategy("Return Air Humidity", new SawStrategy(25.0f, 40.0f, 1.1f, 1000)); + addStrategy("Return Air Temp", new SawStrategy(70.0f, 80.0f, 0.8f, 1000)); addStrategy("Filter Differential Pressure", new SawStrategy(0.0f, 5.0f, 0.2f, 1000)); addStrategy("CW Valve Position", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); // SAT must be greater than SAT Setpoint for this PID to work. addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); + addStrategy("Fan Speed Feedback", new RampStrategy(0.0f, 1.0f, 200)); } /** @@ -141,7 +143,11 @@ State* RunningState::update(Equipment* equipment) } } - setPointValue(equipment, "Fan Speed Feedback", BMS_Speed_Setpoint); + // Fan Speed Feedback dynamically ramp to Fan Speed Setpoint sent to Arduino + Strategy_Behavior* speedFeedback = getStrategy("Fan Speed Feedback"); + if (speedFeedback){ + static_cast(speedFeedback)->setTarget(BMS_Speed_Setpoint); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index a0f6b7d..5c86a7a 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -41,8 +41,9 @@ StandbyState::StandbyState() { // You can add initialization code here if needed. // These strategies are applied at the end of the update function. addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); - addStrategy("Supply Air Temp", new RampStrategy(74.0f, 1.0f, 1000)); - addStrategy("Return Air Temp", new RampStrategy(86.0f, 1.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); + addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); + addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 10.0f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 196db82..409f130 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 49); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 62); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -136,7 +136,7 @@ modbusMap mb_map[] = {IR_FLOAT, 75, 0, "Amps Fan 7"}, {IR_FLOAT, 77, 0, "Amps Fan 8"}, {IR_FLOAT, 79, 0, "Amps Fan 9"}, - {IR_FLOAT, 99, 0, "CRAH Heartbeat"}, // Placeholder - we don't have this from UMAS yet. Not used in logic yet. + {IR_FLOAT, 99, 0, "CRAH Heartbeat"}, {HR_FLOAT, 13, 0, "Fan Speed Setpoint"}, // Receive signal from PLC {HR_FLOAT, 17, 0, "Supply Air Temp Setpoint"}, // Receive signal from PLC @@ -145,7 +145,7 @@ modbusMap mb_map[] = {HR, 25, 0, "BMS Control Source"}, // Receive signal from PLC 0:Speed, 1:Room Temp {HR, 26, 2, "BMS Enable Source"}, // Receive signal from PLC 0:Keypad, 1:DI, 2:BMS {HR_FLOAT, 28, 0, "Fan Speed Feedback"}, - + {HR_FLOAT, 99, 0, "PLC Heartbeat"}, // This will be seconds from PLC - if doesn't change for 15 seconds set BMS Enable Source to Local (0) }; //Size of modbus map used in FOR cycles, automatically calculated. diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index c027708..2aec506 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -22,7 +22,7 @@ */ const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 63); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 66); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ diff --git a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h index a40b037..b78c910 100644 --- a/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h +++ b/src/BMS/HUM/HUM_DriSteem_RTS_RX36_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 67); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 68); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h index d3c2a9e..79b6515 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h @@ -56,8 +56,8 @@ */ modbusMap mb_map[] = { - {HR, 149, 1800, "Speed Cmd"}, // arbitrary register number - receive signal from PLC (hardwire IO in field); expecting rpm (1800 rpm max) - {HR, 151, 0, "Start/Stop"}, // arbitrary register number - receive signal from PLC (hardwire IO in practice) + {HR, 149, 1650, "Speed Cmd"}, // arbitrary register number - receive signal from PLC (hardwire IO in field); expecting rpm (1800 rpm max) + {HR, 151, 1, "Start/Stop"}, // arbitrary register number - receive signal from PLC (hardwire IO in practice) {HR, 152, 0, "HOA Command"}, // arbitrary register number - not used in program {HR, 154, 0, "Run Status"}, // arbitrary register number - 0:off, 1:on (simulated hardwire IO) sending feedback to PLC during simulation. {HR, 155, 1, "Fault Status"}, // arbitrary register number - 0:faulted, 1:not faulted (simulated hardwire IO). When = 0, will turn off VFD. From aa204e615ebeb67df394ac730888d8535af11957 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Thu, 6 Nov 2025 17:40:55 -0700 Subject: [PATCH 21/51] PHX3 uploading to EPMS devices Changed "SEL_2440 (MVG)" to "SEL_2440_MVG" so device can load onto Arduino. Uploaded existing EPMS code to PHX3 EPMS Arduinos. Changes to run status bit of UMAS CRAH. Modified a few PHX3 VFD ACH580 registers from HR to HR_10x. --- platformio.ini | 17 +++++++++++-- src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 4 +-- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 25 ------------------- src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 2 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 4 +-- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 2 +- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 18 ++++++------- src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h | 14 +++++------ .../ATS/ATS_Woodward_DTSC200A_TCP/config.h | 6 ++--- src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h | 8 +++--- src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h | 6 ++--- src/EPMS/GEN/GEN_HSE/config.h | 8 +++--- .../README.md | 0 .../State_Fail.cpp | 0 .../State_Running.cpp | 0 .../State_Standby.cpp | 0 .../{SEL_2440 (MVG) => SEL_2440_MVG}/config.h | 8 +++--- .../{SEL_2440 (MVG) => SEL_2440_MVG}/main.cpp | 0 18 files changed, 55 insertions(+), 67 deletions(-) rename src/EPMS/MVG/{SEL_2440 (MVG) => SEL_2440_MVG}/README.md (100%) rename src/EPMS/MVG/{SEL_2440 (MVG) => SEL_2440_MVG}/State_Fail.cpp (100%) rename src/EPMS/MVG/{SEL_2440 (MVG) => SEL_2440_MVG}/State_Running.cpp (100%) rename src/EPMS/MVG/{SEL_2440 (MVG) => SEL_2440_MVG}/State_Standby.cpp (100%) rename src/EPMS/MVG/{SEL_2440 (MVG) => SEL_2440_MVG}/config.h (88%) rename src/EPMS/MVG/{SEL_2440 (MVG) => SEL_2440_MVG}/main.cpp (100%) diff --git a/platformio.ini b/platformio.ini index efbda27..2ff69aa 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,6 @@ [platformio] - default_envs = CH_York_YVAA_RTU ; Select here the name of the configuration you want to download [env] @@ -232,4 +231,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:GEN_HSE] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = -D USE_MODBUS_IP +build_src_filter = -<*> + + +[env:SEL_2440_MVG] +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/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index ee3284c..86dc254 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -54,7 +54,7 @@ */ modbusMap mb_map[] = { - {COIL, 0, 0, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. + {COIL, 0, 1, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) @@ -99,7 +99,7 @@ modbusMap mb_map[] = {HR, 31, 77, "Sys 2 Operational Code"}, // 77:not running, 78:running, 82:free cooling {HR, 32, 0, "Sys 2 Fault Code"}, // 56:condenser fan VSD warning - {HR, 39, 0, "Local Leaving Temp Setpoint"}, + {HR, 39, 72, "Local Leaving Temp Setpoint"}, {HR_10x, 49, 0, "Sys 2 Condenser Temp"}, {HR_10x, 140, 0, "Sys 1 Fan KW"}, diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index f980695..8fdfcc1 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -119,29 +119,4 @@ void updateAnalogs(Equipment* equipment){ else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Humidity", 65.0f); } -} - -/** - * @brief This function is used to update the Control Mode (feedback), - * based on the selected BMS Control Source and BMS Enable Source. - * - * This is a function used in the update() of the Standby, Running, and Fail States. - * -*/ -void checkHB(Equipment* equipment){ - Modbus_Point* PLC_Heartbeat = equipment -> getModbus_Point ("PLC Heartbeat"); - int BMS_Control_Source = BMS_Control_Source_Pt ? BMS_Control_Source_Pt->getValue() : 0; - int BMS_Enable_Source = BMS_Enable_Source_Pt ? BMS_Enable_Source_Pt->getValue() : 0; - int Control_Mode_Selected = Control_Mode_Pt ? Control_Mode_Pt->getValue() : -1; - - if (BMS_Control_Source == 0 && BMS_Enable_Source == 2) { - Control_Mode_Selected = 0; - } else if (BMS_Control_Source == 1 && BMS_Enable_Source == 2) { - Control_Mode_Selected = 1; - } else if (BMS_Enable_Source == 0) { - Control_Mode_Selected = 2; - } - equipment->setModbus_Point("Control Mode Selected", Control_Mode_Selected); - - equipment->setModbus_Point("General Alarm", 0); } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index eed9417..ceeb819 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -116,7 +116,7 @@ void FailState::enterState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(1); + point->setValue(0); } }; diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index a7b797b..a1c8f16 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -176,7 +176,7 @@ void RunningState::enterState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(0); + point->setValue(1); } } } @@ -201,7 +201,7 @@ void RunningState::exitState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(1); + point->setValue(0); } } } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index 5c86a7a..2b78791 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -126,7 +126,7 @@ void StandbyState::enterState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(1); + point->setValue(0); } }; diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 409f130..186fa3b 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -99,15 +99,15 @@ modbusMap mb_map[] = {IR, 50, 0, "Alarm Fan 7"}, {IR, 54, 0, "Alarm Fan 8"}, {IR, 58, 0, "Alarm Fan 9"}, - {IR, 27, 1, "Run Status Fan 1"}, // Send to PLC - {IR, 31, 1, "Run Status Fan 2"}, // Send to PLC - {IR, 35, 1, "Run Status Fan 3"}, // Send to PLC - {IR, 39, 1, "Run Status Fan 4"}, // Send to PLC - {IR, 43, 1, "Run Status Fan 5"}, // Send to PLC - {IR, 47, 1, "Run Status Fan 6"}, // Send to PLC - {IR, 51, 1, "Run Status Fan 7"}, // Send to PLC - {IR, 55, 1, "Run Status Fan 8"}, // Send to PLC - {IR, 59, 1, "Run Status Fan 9"}, // Send to PLC + {IR, 27, 0, "Run Status Fan 1"}, // Send to PLC + {IR, 31, 0, "Run Status Fan 2"}, // Send to PLC + {IR, 35, 0, "Run Status Fan 3"}, // Send to PLC + {IR, 39, 0, "Run Status Fan 4"}, // Send to PLC + {IR, 43, 0, "Run Status Fan 5"}, // Send to PLC + {IR, 47, 0, "Run Status Fan 6"}, // Send to PLC + {IR, 51, 0, "Run Status Fan 7"}, // Send to PLC + {IR, 55, 0, "Run Status Fan 8"}, // Send to PLC + {IR, 59, 0, "Run Status Fan 9"}, // Send to PLC {IR, 25, 0, "Speed Fan 1"}, {IR, 29, 0, "Speed Fan 2"}, {IR, 33, 0, "Speed Fan 3"}, diff --git a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h index 79b6515..78bff06 100644 --- a/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h +++ b/src/BMS/VFD/PHX3_VFD_ABB_ACH580_RTU/config.h @@ -66,12 +66,12 @@ modbusMap mb_map[] = {HR, 100, 0, "Speed Feedback"}, // 1800 rpm max {HR, 105, 0, "Output Frequency"}, // 60 Hz @100% speed {HR, 106, 0, "Motor Current"}, // 65 FLA - {HR, 109, 0, "Motor Torque"}, // % of nominal torque - {HR, 110, 0, "DC Voltage"}, // approx 678 VDC @100% speed + {HR_10x, 109, 0, "Motor Torque"}, // % of nominal torque + {HR_10x, 110, 0, "DC Voltage"}, // approx 678 VDC @100% speed {HR, 112, 0, "Output Voltage"}, // 480 VAC - {HR, 116, 0, "Motor Shaft Power"}, // 50 hp ~ 36.77 kW + {HR_10x, 116, 0, "Motor Shaft Power"}, // 50 hp ~ 36.77 kW {HR, 118, 0, "Inverter MWh counter"}, - {HR, 119, 0, "Inverter kWh counter"}, + {HR_10x, 119, 0, "Inverter kWh counter"}, {HR, 510, 0, "Inverter Temperature"}, // RJD: Changed from HR_10x to HR, % of fault limit {HR, 519, 0, "Diagnostic Word"}, // not used in program. Bit 9:Drive Over-Temp Alarm @@ -83,10 +83,10 @@ modbusMap mb_map[] = {HR, 4600, 0, "Speed Scaling"}, // ADD: 1800 rpm {HR, 4601, 0, "Frequency Scaling"}, // ADD: 60 Hz {HR, 9905, 0, "Nominal Current"}, // ADD: 65 A - {HR, 9906, 0, "Nominal Voltage"}, // ADD: 480 V - {HR, 9907, 0, "Nominal Frequency"}, // ADD: 60 Hz + {HR_10x, 9906, 0, "Nominal Voltage"}, // ADD: 480 V + {HR_10x, 9907, 0, "Nominal Frequency"}, // ADD: 60 Hz {HR, 9908, 0, "Nominal Speed"}, // ADD: 1800 rpm - {HR, 9909, 0, "Nominal Power"}, // ADD: 50 hp + {HR_10x, 9909, 0, "Nominal Power"}, // ADD: 50 hp }; //Size of modbus map used in FOR cycles, automatically calculated. diff --git a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h index 3f7bcf0..1223b95 100644 --- a/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h +++ b/src/EPMS/ATS/ATS_Woodward_DTSC200A_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 173); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 32, 82); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h index 3887572..22baf7d 100644 --- a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h +++ b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #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(172, 17, 22, 152); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 22, 254); /**< @brief The gateway IP address. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 90); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h b/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h index b77bc05..7dd406b 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "QTS_CDR_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 33, 154); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 33, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 32, 102); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/GEN/GEN_HSE/config.h b/src/EPMS/GEN/GEN_HSE/config.h index 49fa677..f5c4439 100644 --- a/src/EPMS/GEN/GEN_HSE/config.h +++ b/src/EPMS/GEN/GEN_HSE/config.h @@ -21,10 +21,10 @@ * @{ */ #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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 81); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/MVG/SEL_2440 (MVG)/README.md b/src/EPMS/MVG/SEL_2440_MVG/README.md similarity index 100% rename from src/EPMS/MVG/SEL_2440 (MVG)/README.md rename to src/EPMS/MVG/SEL_2440_MVG/README.md diff --git a/src/EPMS/MVG/SEL_2440 (MVG)/State_Fail.cpp b/src/EPMS/MVG/SEL_2440_MVG/State_Fail.cpp similarity index 100% rename from src/EPMS/MVG/SEL_2440 (MVG)/State_Fail.cpp rename to src/EPMS/MVG/SEL_2440_MVG/State_Fail.cpp diff --git a/src/EPMS/MVG/SEL_2440 (MVG)/State_Running.cpp b/src/EPMS/MVG/SEL_2440_MVG/State_Running.cpp similarity index 100% rename from src/EPMS/MVG/SEL_2440 (MVG)/State_Running.cpp rename to src/EPMS/MVG/SEL_2440_MVG/State_Running.cpp diff --git a/src/EPMS/MVG/SEL_2440 (MVG)/State_Standby.cpp b/src/EPMS/MVG/SEL_2440_MVG/State_Standby.cpp similarity index 100% rename from src/EPMS/MVG/SEL_2440 (MVG)/State_Standby.cpp rename to src/EPMS/MVG/SEL_2440_MVG/State_Standby.cpp diff --git a/src/EPMS/MVG/SEL_2440 (MVG)/config.h b/src/EPMS/MVG/SEL_2440_MVG/config.h similarity index 88% rename from src/EPMS/MVG/SEL_2440 (MVG)/config.h rename to src/EPMS/MVG/SEL_2440_MVG/config.h index 3b97232..88714a4 100644 --- a/src/EPMS/MVG/SEL_2440 (MVG)/config.h +++ b/src/EPMS/MVG/SEL_2440_MVG/config.h @@ -21,10 +21,10 @@ * @{ */ #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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 88); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/MVG/SEL_2440 (MVG)/main.cpp b/src/EPMS/MVG/SEL_2440_MVG/main.cpp similarity index 100% rename from src/EPMS/MVG/SEL_2440 (MVG)/main.cpp rename to src/EPMS/MVG/SEL_2440_MVG/main.cpp From 210a53800e824f143ea458c8e63c0d4141ea6465 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Mon, 10 Nov 2025 08:22:18 -0600 Subject: [PATCH 22/51] MVG template added --- platformio.ini | 13 +- src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md | 33 +++ .../MVG/MVG_SC_EC_M505_TCP/State_Fail.cpp | 81 ++++++ .../MVG/MVG_SC_EC_M505_TCP/State_Running.cpp | 272 ++++++++++++++++++ .../MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp | 90 ++++++ src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h | 86 ++++++ src/EPMS/MVG/MVG_SC_EC_M505_TCP/main.cpp | 86 ++++++ 7 files changed, 659 insertions(+), 2 deletions(-) create mode 100644 src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md create mode 100644 src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Fail.cpp create mode 100644 src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp create mode 100644 src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp create mode 100644 src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h create mode 100644 src/EPMS/MVG/MVG_SC_EC_M505_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index 2ff69aa..12dc711 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ [platformio] -default_envs = CH_York_YVAA_RTU ; Select here the name of the configuration you want to download +default_envs = MVG_SC_EC_M505_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM16 @@ -245,4 +245,13 @@ 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:MVG_SC_EC_M505_TCP] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = + -D USE_MODBUS_IP, + -D USE_LED +build_src_filter = -<*> + \ No newline at end of file diff --git a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md new file mode 100644 index 0000000..355156f --- /dev/null +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md @@ -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 diff --git a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Fail.cpp b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Fail.cpp new file mode 100644 index 0000000..8bc0385 --- /dev/null +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Fail.cpp @@ -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 +#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/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp new file mode 100644 index 0000000..5215ef6 --- /dev/null +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp @@ -0,0 +1,272 @@ +/** + * @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"); + float StateCtrl = getPointValue(equipment, "Px_Mode"); + if (StateCtrl == 1.0f) { + return new RunningState(); + } + + float W1 = getPointValue(equipment, "Px_W1"); + float W2 = getPointValue(equipment, "Px_W2"); + float W3 = getPointValue(equipment, "Px_W3"); + float W4 = getPointValue(equipment, "Px_W4"); + float W5 = getPointValue(equipment, "Px_W5"); + float W6 = getPointValue(equipment, "Px_W6"); + + switch (static_cast(W1)){ + case 0: + setBitValue(equipment, "MVG_STS_01", 0, false); + setBitValue(equipment, "MVG_STS_01", 1, false); + setBitValue(equipment, "MVG_STS_01", 2, false); + break; + case 1: + setBitValue(equipment, "MVG_STS_01", 0, true); + setBitValue(equipment, "MVG_STS_01", 1, false); + setBitValue(equipment, "MVG_STS_01", 2, false); + break; + case 2: + setBitValue(equipment, "MVG_STS_01", 0, false); + setBitValue(equipment, "MVG_STS_01", 1, true); + setBitValue(equipment, "MVG_STS_01", 2, false); + break; + case 3: + setBitValue(equipment, "MVG_STS_01", 0, true); + setBitValue(equipment, "MVG_STS_01", 1, false); + setBitValue(equipment, "MVG_STS_01", 2, true); + break; + default: + setBitValue(equipment, "MVG_STS_01", 0, false); + setBitValue(equipment, "MVG_STS_01", 1, false); + setBitValue(equipment, "MVG_STS_01", 2, false); + break; + } + + switch (static_cast(W2)){ + case 0: + setBitValue(equipment, "MVG_STS_01", 3, false); + setBitValue(equipment, "MVG_STS_01", 4, false); + setBitValue(equipment, "MVG_STS_01", 5, false); + break; + case 1: + setBitValue(equipment, "MVG_STS_01", 3, true); + setBitValue(equipment, "MVG_STS_01", 4, false); + setBitValue(equipment, "MVG_STS_01", 5, false); + break; + case 2: + setBitValue(equipment, "MVG_STS_01", 3, false); + setBitValue(equipment, "MVG_STS_01", 4, true); + setBitValue(equipment, "MVG_STS_01", 5, false); + break; + case 3: + setBitValue(equipment, "MVG_STS_01", 3, true); + setBitValue(equipment, "MVG_STS_01", 4, false); + setBitValue(equipment, "MVG_STS_01", 5, true); + break; + default: + setBitValue(equipment, "MVG_STS_01", 3, false); + setBitValue(equipment, "MVG_STS_01", 4, false); + setBitValue(equipment, "MVG_STS_01", 5, false); + break; + } + + switch (static_cast(W3)){ + case 0: + setBitValue(equipment, "MVG_STS_01", 6, false); + setBitValue(equipment, "MVG_STS_01", 7, false); + setBitValue(equipment, "MVG_STS_02", 0, false); + break; + case 1: + setBitValue(equipment, "MVG_STS_01", 6, true); + setBitValue(equipment, "MVG_STS_01", 7, false); + setBitValue(equipment, "MVG_STS_02", 0, false); + break; + case 2: + setBitValue(equipment, "MVG_STS_01", 6, false); + setBitValue(equipment, "MVG_STS_01", 7, true); + setBitValue(equipment, "MVG_STS_02", 0, false); + break; + case 3: + setBitValue(equipment, "MVG_STS_01", 6, true); + setBitValue(equipment, "MVG_STS_01", 7, false); + setBitValue(equipment, "MVG_STS_02", 0, true); + break; + default: + setBitValue(equipment, "MVG_STS_01", 6, false); + setBitValue(equipment, "MVG_STS_01", 7, false); + setBitValue(equipment, "MVG_STS_02", 0, false); + break; + } + + switch (static_cast(W4)){ + case 0: + setBitValue(equipment, "MVG_STS_02", 1, false); + setBitValue(equipment, "MVG_STS_02", 2, false); + setBitValue(equipment, "MVG_STS_02", 3, false); + break; + case 1: + setBitValue(equipment, "MVG_STS_02", 1, true); + setBitValue(equipment, "MVG_STS_02", 2, false); + setBitValue(equipment, "MVG_STS_02", 3, false); + break; + case 2: + setBitValue(equipment, "MVG_STS_02", 1, false); + setBitValue(equipment, "MVG_STS_02", 2, true); + setBitValue(equipment, "MVG_STS_02", 3, false); + break; + case 3: + setBitValue(equipment, "MVG_STS_02", 1, true); + setBitValue(equipment, "MVG_STS_02", 2, false); + setBitValue(equipment, "MVG_STS_02", 3, true); + break; + default: + setBitValue(equipment, "MVG_STS_02", 1, false); + setBitValue(equipment, "MVG_STS_02", 2, false); + setBitValue(equipment, "MVG_STS_02", 3, false); + break; + } + + switch (static_cast(W5)){ + case 0: + setBitValue(equipment, "MVG_STS_02", 4, false); + setBitValue(equipment, "MVG_STS_02", 5, false); + setBitValue(equipment, "MVG_STS_02", 6, false); + break; + case 1: + setBitValue(equipment, "MVG_STS_02", 4, true); + setBitValue(equipment, "MVG_STS_02", 5, false); + setBitValue(equipment, "MVG_STS_02", 6, false); + break; + case 2: + setBitValue(equipment, "MVG_STS_02", 4, false); + setBitValue(equipment, "MVG_STS_02", 5, true); + setBitValue(equipment, "MVG_STS_02", 6, false); + break; + case 3: + setBitValue(equipment, "MVG_STS_02", 4, true); + setBitValue(equipment, "MVG_STS_02", 5, false); + setBitValue(equipment, "MVG_STS_02", 6, true); + break; + default: + setBitValue(equipment, "MVG_STS_02", 4, false); + setBitValue(equipment, "MVG_STS_02", 5, false); + setBitValue(equipment, "MVG_STS_02", 6, false); + break; + } + + switch (static_cast(W6)){ + case 0: + setBitValue(equipment, "MVG_STS_02", 7, false); + setBitValue(equipment, "MVG_STS_03", 0, false); + setBitValue(equipment, "MVG_STS_03", 1, false); + break; + case 1: + setBitValue(equipment, "MVG_STS_02", 7, true); + setBitValue(equipment, "MVG_STS_03", 0, false); + setBitValue(equipment, "MVG_STS_03", 1, false); + break; + case 2: + setBitValue(equipment, "MVG_STS_02", 7, false); + setBitValue(equipment, "MVG_STS_03", 0, true); + setBitValue(equipment, "MVG_STS_03", 1, false); + break; + case 3: + setBitValue(equipment, "MVG_STS_02", 7, true); + setBitValue(equipment, "MVG_STS_03", 0, false); + setBitValue(equipment, "MVG_STS_03", 1, true); + break; + default: + setBitValue(equipment, "MVG_STS_02", 7, false); + setBitValue(equipment, "MVG_STS_03", 0, false); + setBitValue(equipment, "MVG_STS_03", 1, false); + break; + } + + + + // 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..."); + setPointValue(equipment, "MVG_STS_01", 0); + setPointValue(equipment, "MVG_STS_02", 0); + setPointValue(equipment, "MVG_STS_03", 0); +} \ No newline at end of file diff --git a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp new file mode 100644 index 0000000..92daf4c --- /dev/null +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp @@ -0,0 +1,90 @@ +/** + * @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"); + float StateCtrl = getPointValue(equipment, "Px_Mode"); + if (StateCtrl == 2.0f) { + return new RunningState(); + } + + + // 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/MVG/MVG_SC_EC_M505_TCP/config.h b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h new file mode 100644 index 0000000..a29ec84 --- /dev/null +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h @@ -0,0 +1,86 @@ +/** + * @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, 9, 0, "Px_Mode"}, + {HR, 10, 0, "Px_W1"}, + {HR, 11, 0, "Px_W2"}, + {HR, 12, 0, "Px_W3"}, + {HR, 13, 0, "Px_W4"}, + {HR, 14, 0, "Px_W5"}, + {HR, 15, 0, "Px_W6"}, + {HR, 1049, 0, "MVG_STS_01"}, + {HR, 1050, 0, "MVG_STS_02"}, + {HR, 1051, 0, "MVG_STS_03"}, +}; +//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/MVG/MVG_SC_EC_M505_TCP/main.cpp b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/main.cpp @@ -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 +#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); + } +} From 587945cf1f117af3531d3cb999179a5b20febb13 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Mon, 10 Nov 2025 09:24:44 -0600 Subject: [PATCH 23/51] MVG Template created --- platformio.ini | 9 ++- src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md | 59 ++++++++++++------- .../MVG/MVG_SC_EC_M505_TCP/State_Running.cpp | 11 ++-- .../MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp | 10 ++-- src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h | 10 ++-- 5 files changed, 55 insertions(+), 44 deletions(-) diff --git a/platformio.ini b/platformio.ini index 12dc711..97e5cbb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,7 @@ default_envs = MVG_SC_EC_M505_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM16 +upload_port = COM26 [common_env_options] framework = arduino @@ -251,7 +251,6 @@ build_src_filter = -<*> + platform = espressif32 board = dfrobot_firebeetle2_esp32e extends = common_env_options -build_flags = - -D USE_MODBUS_IP, - -D USE_LED -build_src_filter = -<*> + \ No newline at end of file +build_flags = -D USE_MODBUS_IP, +build_src_filter = -<*> + + diff --git a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md index 355156f..4f156e3 100644 --- a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/README.md @@ -1,33 +1,48 @@ -# EQUIPMENT_TYPE MANUFACTURER MODEL TCP +# Daikin Chiller (RTU) Emulator -## Brief Introduction -Equipment specifc details that make it different from other devices +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. -## List of Equipmentt -This cofiguration has been used for these models: -* **Model**: 09-15-22 -* **Model**: 09-15-23 -* **Model**: 09-15-25 +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. -* **Microcontroller**: [Firebeetle 2 ESP32.](https://www.dfrobot.com/product-2231.html) +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`. --- -## States and Strategies -Provide a brief description of what variables and strategies were used in this configuraiton +## How to Customize for a New Chiller -### Standby State -* **Equipment running**: set to 0 -* **Common Alarm**: set to 0 -* **SAT temperature**: set to 85 +To adapt this template for a new chiller, follow these steps. -### Running State -* **Equipment running**: set to 1 -* **SAT temperature**: **Ramp Strategy** set to 65 deg setpoint +### 1. Configure Device-Specific Parameters (`config.h`) -### Fail State -* **Commong Alarm**: set to 1 -* **SAT temperature**: **Ramp Strategy** set to 105 deg setpointset +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/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp index 5215ef6..f3faa44 100644 --- a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Running.cpp @@ -38,6 +38,7 @@ */ template<> RunningState::RunningState() { + } /** @@ -59,7 +60,7 @@ State* RunningState::update(Equipment* equipment) Serial.println("Running update function"); float StateCtrl = getPointValue(equipment, "Px_Mode"); if (StateCtrl == 1.0f) { - return new RunningState(); + return new StandbyState(); } float W1 = getPointValue(equipment, "Px_W1"); @@ -68,6 +69,7 @@ State* RunningState::update(Equipment* equipment) float W4 = getPointValue(equipment, "Px_W4"); float W5 = getPointValue(equipment, "Px_W5"); float W6 = getPointValue(equipment, "Px_W6"); + // Apply any strategies defined for the standby state switch (static_cast(W1)){ case 0: @@ -236,10 +238,6 @@ State* RunningState::update(Equipment* equipment) setBitValue(equipment, "MVG_STS_03", 1, false); break; } - - - - // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; } @@ -254,7 +252,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 - + } /** @@ -269,4 +267,5 @@ void RunningState::exitState(Equipment* equipment) { setPointValue(equipment, "MVG_STS_01", 0); setPointValue(equipment, "MVG_STS_02", 0); setPointValue(equipment, "MVG_STS_03", 0); + } \ No newline at end of file diff --git a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp index 92daf4c..6dad7d4 100644 --- a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/State_Standby.cpp @@ -38,8 +38,7 @@ template<> StandbyState::StandbyState() { // You can add initialization code here if needed - - + } /** @@ -60,9 +59,6 @@ State* StandbyState::update(Equipment* equipment) if (StateCtrl == 2.0f) { return new RunningState(); } - - - // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; } @@ -77,8 +73,10 @@ 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. diff --git a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h index a29ec84..3be4ccc 100644 --- a/src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h +++ b/src/EPMS/MVG/MVG_SC_EC_M505_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #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. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 82); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -70,7 +70,7 @@ modbusMap mb_map[] = {HR, 1049, 0, "MVG_STS_01"}, {HR, 1050, 0, "MVG_STS_02"}, {HR, 1051, 0, "MVG_STS_03"}, -}; +}; //Size of modbus map used in FOR cycles, automatically calculated. /** From bd3814aca7fc2024771dda8ca34e03922dc4554f Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Mon, 10 Nov 2025 16:28:31 -0600 Subject: [PATCH 24/51] gen --- platformio.ini | 9 +- src/EPMS/GEN/GEN_CAT_EMCP4_TCP/config.h | 1 + src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md | 33 +++++ src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp | 81 +++++++++++ .../GEN/GEN_CAT_GCCP_TCP/State_Running.cpp | 92 ++++++++++++ .../GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp | 89 ++++++++++++ src/EPMS/GEN/GEN_CAT_GCCP_TCP/config.h | 133 ++++++++++++++++++ src/EPMS/GEN/GEN_CAT_GCCP_TCP/main.cpp | 86 +++++++++++ 8 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md create mode 100644 src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp create mode 100644 src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Running.cpp create mode 100644 src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp create mode 100644 src/EPMS/GEN/GEN_CAT_GCCP_TCP/config.h create mode 100644 src/EPMS/GEN/GEN_CAT_GCCP_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index 97e5cbb..5552fe6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ [platformio] -default_envs = MVG_SC_EC_M505_TCP ; Select here the name of the configuration you want to download +default_envs = GEN_CAT_GCCP_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM26 @@ -254,3 +254,10 @@ extends = common_env_options build_flags = -D USE_MODBUS_IP, build_src_filter = -<*> + +[env:GEN_CAT_GCCP_TCP] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = -D USE_MODBUS_IP, +build_src_filter = -<*> + + diff --git a/src/EPMS/GEN/GEN_CAT_EMCP4_TCP/config.h b/src/EPMS/GEN/GEN_CAT_EMCP4_TCP/config.h index b45aea7..76b42f4 100644 --- a/src/EPMS/GEN/GEN_CAT_EMCP4_TCP/config.h +++ b/src/EPMS/GEN/GEN_CAT_EMCP4_TCP/config.h @@ -60,6 +60,7 @@ */ modbusMap mb_map[] = { // ESP8266 Modbus server uses 0-based addressing, while Modbus Poll uses 1-based addressing. + {HR, 48899, 0, "Alm01" }, // 448900 {HR, 48898, 0, "Alm02" }, // 448899 {HR, 48905, 0, "Alm03" }, // 448906 diff --git a/src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md new file mode 100644 index 0000000..355156f --- /dev/null +++ b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/README.md @@ -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 diff --git a/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp new file mode 100644 index 0000000..8bc0385 --- /dev/null +++ b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Fail.cpp @@ -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 +#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/GEN/GEN_CAT_GCCP_TCP/State_Running.cpp b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Running.cpp new file mode 100644 index 0000000..44afe79 --- /dev/null +++ b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Running.cpp @@ -0,0 +1,92 @@ +/** + * @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"); + float Mode = getPointValue(equipment, "PxMode"); + if (static_cast(Mode) == 2 ){ + return new StandbyState(); + } + // 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/GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp new file mode 100644 index 0000000..90f8eb3 --- /dev/null +++ b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/State_Standby.cpp @@ -0,0 +1,89 @@ +/** + * @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"); + float Mode = getPointValue(equipment, "PxMode"); + if (static_cast(Mode) == 2 ){ + return new RunningState(); + } + + // 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/GEN/GEN_CAT_GCCP_TCP/config.h b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/config.h new file mode 100644 index 0000000..72959e4 --- /dev/null +++ b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/config.h @@ -0,0 +1,133 @@ +/** + * @file config.h + * @brief Main configuration file for the GEN CAT EMCP4 + * @author Zach Gutierrez + * @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[] = { + // ESP8266 Modbus server uses 0-based addressing, while Modbus Poll uses 1-based addressing. + {HR, 9, 0, "PxMode" }, // 448900 High_Coolant_Temp_Warning + {HR, 10, 0, "Px01" }, // 448899 Low_Coolant_Temp + {HR, 11, 0, "Px02" }, // 448906 Unexpected_Engine_Shutdown + + {HR, 48900, 0, "Alm01" }, // 448900 High_Coolant_Temp_Warning + {HR, 48899, 0, "Alm02" }, // 448899 Low_Coolant_Temp + {HR, 48906, 0, "Alm03" }, // 448906 Unexpected_Engine_Shutdown + {HR, 48897, 0, "Alm04" }, // 448897 Emergency_Stop + {HR, 48901, 0, "Alm05" }, // 448901 High_Coolant_Temp_Alarm + {HR, 48904, 0, "Alm06" }, // 448904 Engine_Overspeed + {HR, 48902, 0, "Alm07" }, // 448902 Low_Oil_Pressure_Warning + {HR, 48903, 0, "Alm08" }, // 448903 Low_Oil_Pressure_Alarm + {HR, 48908, 0, "Fuel_LoLo" }, // 448908 Fuel_LoLo + {HR, 48913, 0, "Alm10" }, // 448913 Low_Battery_Voltage + {HR, 48898, 0, "Alm11" }, // 448898 Engine_Overcrank + {HR, 48915, 0, "Fuel_Hi" }, // 448915 Fuel_Hi + {HR, 48907, 0, "Fuel_Lo" }, // 448907 Fuel_Lo + {HR, 48912, 0, "Alm14" }, // 448912 High_Battery_Voltage + {HR, 48905, 0, "Common_Alarm" }, // 448905 Common_Alarm + {HR, 48914, 0, "Batt_Charge_Fail" }, // 448914 Battery_Charger_Failure + {HR, 48916, 0, "EPS_Supp_Load" }, // 448916 EPS_Supplying_Load + {HR, 8655, 0, "Bkr_State" }, // 48655 Gen_Breaker_State + {HR, 1025, 0, "Oil Pressure" }, // 41025 Engine_Oil_Pressure + {HR, 1026, 0, "Coolant Temp" }, // 41026 Coolant_Temperature_degC + {HR, 1027, 0, "Oil_Temp_degC" }, // 41027 Oil_Temperature_degC + {HR, 1030, 0, "Battery_Voltage" }, // 41030 Battery_Voltage + {HR, 1031, 0, "Engine_Speed" }, // 41031 Engine_Speed + {HR, 1032, 0, "Freq" }, // 41032 Freq + {HR, 1033, 0, "Volts_AN" }, // 41033 Volts_AN + {HR, 1035, 0, "Volts_BN" }, // 41035 Volts_BN + {HR, 1037, 0, "Volts_CN" }, // 41037 Volts_CN + {HR, 1039, 0, "Volts_AB" }, // 41039 Volts_AB + {HR, 1041, 0, "Volts_BC" }, // 41041 Volts_BC + {HR, 1043, 0, "Volts_CA" }, // 41043 Volts_CA + {HR, 1045, 0, "Amps_A" }, // 41045 Amps_A + {HR, 1047, 0, "Amps_B" }, // 41047 Amps_B + {HR, 1049, 0, "Amps_C" }, // 41049 Amps_C + {HR, 1053, 0, "kW_A" }, // 41053 kW_A + {HR, 1055, 0, "kW_B" }, // 41055 kW_B + {HR, 1057, 0, "kW_C" }, // 41057 kW_C + {HR, 1289, 0, "L_Exhaust_degC" }, // 41289 Left_Exhaust_Temp_degC + {HR, 1290, 0, "R_Exhaust_degC" }, // 41290 Right_Exhaust_Temp_degC + {HR, 1355, 0, "Percent_Load" }, // 41355 Percent_Load + {HR, 1537, 0, "kW_Tot" }, // 41537 kW + {HR, 1539, 0, "kVA_A" }, // 41539 kVA_A + {HR, 1541, 0, "kVA_B" }, // 41541 kVA_B + {HR, 1543, 0, "kVA_C" }, // 41543 kVA_C + {HR, 1545, 0, "kVA_Tot" }, // 41545 kVA + {HR, 1553, 0, "kVAR_Tot" }, // 41553 kVAR + {HR, 1558, 0, "PF_Tot" }, // 41558 PF + {HR, 1799, 0, "TTL_Run_Hours" }, // 41799 TTL_Run_Hours + {HR, 1801, 0, "kWh_Tot" }, // 41801 kWh + {HR, 1809, 0, "TTL_Starts" }, // 41809 TTL_Engine_Starts + {HR, 48909, 0, "Auto_Mode" }, // 448909 Auto_Mode + {HR, 48910, 0, "Stop_Mode" }, // 448910 Stop_Mode + {HR, 48911, 0, "Manual_Mode" }, // 448911 Manual_Mode + {HR, 772, 0, "Gen_Sts" } // 400772 Generator Status +}; +//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/GEN/GEN_CAT_GCCP_TCP/main.cpp b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/EPMS/GEN/GEN_CAT_GCCP_TCP/main.cpp @@ -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 +#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); + } +} From 96f68f8d43aa4dc07a56e23e7667d0ae5e169fc8 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Fri, 14 Nov 2025 11:24:55 -0600 Subject: [PATCH 25/51] Breaker ABB Emax 2 Configuration of Breaker ABB Emax 2 Template --- platformio.ini | 4 +- .../BKR_ABB_EMax2_TCP/State_Running.cpp | 50 ++++++++++++++++++- .../BKR_ABB_EMax2_TCP/State_Standby.cpp | 28 ++++++++++- src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h | 44 ++++++++-------- 4 files changed, 101 insertions(+), 25 deletions(-) diff --git a/platformio.ini b/platformio.ini index 5552fe6..bf5c678 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,10 +9,10 @@ [platformio] -default_envs = GEN_CAT_GCCP_TCP ; Select here the name of the configuration you want to download +default_envs = BKR_ABB_EMax2_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM26 +upload_port = COM19 [common_env_options] framework = arduino diff --git a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Running.cpp b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Running.cpp index b9e4a99..6d6c693 100644 --- a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Running.cpp +++ b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Running.cpp @@ -38,6 +38,13 @@ */ template<> RunningState::RunningState() { + addStrategy("V_AB", new SingleValueStrategy(4800.0F, 5.0f, 1000)); + addStrategy("V_BC", new SingleValueStrategy(4800.0F, 5.0f, 1000)); + addStrategy("V_CA", new SingleValueStrategy(4800.0F, 5.0f, 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 +64,48 @@ 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, "PxControl"); + if (State_Ctrl == 0.0f){ + return new StandbyState(); + } + if (State_Ctrl == 1.0f){ + setBitValue(equipment, "CB_Position", 0, true); + setBitValue(equipment, "CB_Position", 12, false); + } + if (State_Ctrl == 2.0f){ + return new StandbyState(); + } + + float volts_AB = getPointValue(equipment, "V_AB"); + float volts_BC = getPointValue(equipment, "V_BC"); + float volts_AC = getPointValue(equipment, "V_CA"); + + setPointValue(equipment, "V_AN", volts_AB/1.732f); + setPointValue(equipment, "V_BN", volts_BC/1.732f); + setPointValue(equipment, "V_CN", volts_AC/1.732f); + + + int I_load = getPointValue(equipment, "PxLoad"); + int I_rating = getPointValue(equipment, "PxRating"); + float load = static_cast(I_load); + float rating = static_cast(I_rating); + float real_load = rating * (load/100.0f); + setPointValue(equipment, "Amps A", real_load * 10.0f); + setPointValue(equipment, "Amps B", real_load * 10.0f); + setPointValue(equipment, "Amps C", real_load * 10.0f); + setPointValue(equipment, "Amps G", volts_AB * 0.037f); + setPointValue(equipment, "Amps N", volts_BC * 0.034f); + + + + + float kva = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load * (0.92f))/100000.0f; + float kw = (1.732f * ((volts_AB + volts_BC + volts_AC)/4.0f) * real_load )/10000.0f; + + setPointValue(equipment, "kW", kw); + setPointValue(equipment, "kVA", kva); + setPointValue(equipment, "kVA2", kva); + setPointValue(equipment, "kWh", 1724.0f); // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; diff --git a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Standby.cpp b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Standby.cpp index 20029d1..51e0f25 100644 --- a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/State_Standby.cpp @@ -56,7 +56,18 @@ 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, "PxControl"); + if (State_Ctrl == 1.0f){ + return new RunningState(); + } + if (State_Ctrl == 0.0f){ + setBitValue(equipment, "CB_Position", 0, false); + setBitValue(equipment, "CB_Position", 12, false); + } + if (State_Ctrl == 2.0f){ + setBitValue(equipment, "CB_Position", 0, false); + setBitValue(equipment, "CB_Position", 12, true); + } // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -72,6 +83,21 @@ template<> void StandbyState::enterState(Equipment* equipment) { // Logic to run when the equipment enters this state Serial.println("Enter Standby State..."); + setPointValue(equipment, "V_AB", 0.0f); + setPointValue(equipment, "V_BC", 0.0f); + setPointValue(equipment, "V_CA", 0.0f); + setPointValue(equipment, "V_AN", 0.0f); + setPointValue(equipment, "V_BN", 0.0f); + setPointValue(equipment, "V_CN", 0.0f); + setPointValue(equipment, "Amps A", 0.0f); + setPointValue(equipment, "Amps B", 0.0f); + setPointValue(equipment, "Amps C", 0.0f); + setPointValue(equipment, "Amps G", 0.0f); + setPointValue(equipment, "Amps N", 0.0f); + setPointValue(equipment, "kW", 0.0f); + setPointValue(equipment, "k_VA", 0.0f); + setPointValue(equipment, "k_VA2", 0.0f); + setPointValue(equipment, "kWh", 0.0f); } /** diff --git a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h index 22baf7d..7728a3c 100644 --- a/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h +++ b/src/EPMS/Breaker/BKR_ABB_EMax2_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ - const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 90); /**< @brief The static IP address for the device. */ - IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ + const char *ssid = "wifi"; /**< @brief The SSID of the WiFi network. */ + const char *password = "password"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(192, 168, 1, 170); /**< @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; @@ -63,23 +63,25 @@ modbusMap mb_map[] = { // Convert from ESP8266 to traditional Modbus addressing: subtract 30001/40001. // Input Registers (3x) - Floating Point (MSB & LSB) - {IR, 40, 0, "CB_Position" }, // 300041.0 - Circuit Breaker Position - {IR, 40, 0, "CB_Trip" }, // 300041.12 - Circuit Breaker Tripped - {IR_LONG, 100, 0, "Amps_A" }, //DWORD - {IR_LONG, 102, 0, "Amps_B" }, //DWORD - {IR_LONG, 104, 0, "Amps_C" }, //DWORD - {IR_LONG, 106, 0, "Amps_N" }, //DWORD - {IR_LONG, 108, 0, "Amps_G" }, //DWORD - {IR, 150, 0, "V_AN" }, //WORD - {IR, 151, 0, "V_BN" }, //WORD - {IR, 152, 0, "V_CN" }, //WORD - {IR, 154, 0, "V_AB" }, //WORD - {IR, 155, 0, "V_BC" }, //WORD - {IR, 156, 0, "V_CA" }, //WORD - {IR_LONG, 222, 0, "k_VA" }, //LONG - {IR_LONG, 206, 0, "kW" }, //LONG - {IR_LONG, 304, 0, "kWh" }, //LONG - {IR, 253, 0, "k_VA" }, //SHORT + {HR, 9, 0, "PxControl"}, //Open-Close Cmd + {HR, 10, 0, "PxLoad"}, //Adjustble Load + {HR, 11, 0, "PxRating"}, //Max amp to calculate kw, kVA, etc + {IR, 39, 0, "CB_Position" }, // 300041.0 - Circuit Breaker Position || 300041.12 - Circuit Breaker Tripped + {IR_LONG, 99, 0, "Amps A" }, //DWORD + {IR_LONG, 101, 0, "Amps B" }, //DWORD + {IR_LONG, 103, 0, "Amps C" }, //DWORD + {IR_LONG, 105, 0, "Amps N" }, //DWORD + {IR_LONG, 107, 0, "Amps G" }, //DWORD + {IR, 149, 0, "V_AN" }, //WORD + {IR, 150, 0, "V_BN" }, //WORD + {IR, 151, 0, "V_CN" }, //WORD + {IR, 153, 0, "V_AB" }, //WORD + {IR, 154, 0, "V_BC" }, //WORD + {IR, 155, 0, "V_CA" }, //WORD + {IR_LONG, 221, 0, "k_VA" }, //LONG + {IR_LONG, 205, 0, "kW" }, //LONG + {IR_LONG, 303, 0, "kWh" }, //LONG + {IR, 252, 0, "k_VA2" }, //SHORT }; //Size of modbus map used in FOR cycles, automatically calculated. From 5259754a66585131bd4a74f9d8dd8fa5dd10aa22 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Wed, 26 Nov 2025 12:47:06 -0700 Subject: [PATCH 26/51] updates from Schertz site visit Added 40029, 30100, 40100 --- platformio.ini | 11 +++++++-- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 2 -- src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 8 ++++-- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 18 ++++++++++---- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 9 ++++--- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 26 +++++++++++--------- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/platformio.ini b/platformio.ini index cb47d6d..26350a5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,10 +11,10 @@ [platformio] -default_envs = CH_York_YVAA_RTU ; Select here the name of the configuration you want to download +default_envs = CRAH_UMAS_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM9 +upload_port = COM11 [common_env_options] framework = arduino @@ -200,3 +200,10 @@ platform = espressif32 board = dfrobot_firebeetle2_esp32e extends = common_env_options build_src_filter = -<*> + + +[env:CRAH_UMAS_TCP] +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/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index 056bf7b..8fdfcc1 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -112,7 +112,6 @@ void updateAnalogs(Equipment* equipment){ else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Temp", 104.0f); } - else equipment->setModbus_Point("Return Air Temp", 74.0f); if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Humidity", 15.0f); @@ -120,5 +119,4 @@ void updateAnalogs(Equipment* equipment){ else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ equipment->setModbus_Point("Return Air Humidity", 65.0f); } - else equipment->setModbus_Point("Return Air Humidity", 35.0f); } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index eafcf6b..ceeb819 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -16,6 +16,7 @@ #include "Strategies/Strategy_Ramp.h" #include "Strategies/Strategy_SingleValue.h" #include "Strategies/Strategy_PID.h" +#include "Strategies/Strategy_Saw.h" #include "States/State_Standby.h" #include "States/State_Running.h" #include "States/State_Fail.h" @@ -39,6 +40,9 @@ FailState::FailState(const std::vector& activeAlarms) { // Fan speed --> 0, Run Status --> 0, Amps --> 0 addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); + addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); + addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 10.0f, 1000)); @@ -57,7 +61,7 @@ FailState::FailState(const std::vector& activeAlarms) { addStrategy("Amps Fan 7", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 8", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 9", new RampStrategy(0.0f, 4.5f, 1000)); - + addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); } /** @@ -112,7 +116,7 @@ void FailState::enterState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(1); + point->setValue(0); } }; diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index f85524b..a1c8f16 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -71,11 +71,13 @@ RunningState::RunningState() { addStrategy("Operating Hours Fan 7", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 8", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 9", new TotalizerStrategy(1000)); - addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.0f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan - addStrategy("Return Air Temp", new SawStrategy(70.0f, 80.0f, 1.0f, 1000)); + addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.2f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan + addStrategy("Return Air Humidity", new SawStrategy(25.0f, 40.0f, 1.1f, 1000)); + addStrategy("Return Air Temp", new SawStrategy(70.0f, 80.0f, 0.8f, 1000)); addStrategy("Filter Differential Pressure", new SawStrategy(0.0f, 5.0f, 0.2f, 1000)); addStrategy("CW Valve Position", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); // SAT must be greater than SAT Setpoint for this PID to work. - + addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); + addStrategy("Fan Speed Feedback", new RampStrategy(0.0f, 1.0f, 200)); } /** @@ -141,6 +143,12 @@ State* RunningState::update(Equipment* equipment) } } + // Fan Speed Feedback dynamically ramp to Fan Speed Setpoint sent to Arduino + Strategy_Behavior* speedFeedback = getStrategy("Fan Speed Feedback"); + if (speedFeedback){ + static_cast(speedFeedback)->setTarget(BMS_Speed_Setpoint); + } + // Apply any strategies defined for the standby state _applyStrategies(equipment); return nullptr; @@ -168,7 +176,7 @@ void RunningState::enterState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(0); + point->setValue(1); } } } @@ -193,7 +201,7 @@ void RunningState::exitState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(1); + point->setValue(0); } } } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index 70be6d4..2b78791 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -41,8 +41,9 @@ StandbyState::StandbyState() { // You can add initialization code here if needed. // These strategies are applied at the end of the update function. addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); - addStrategy("Supply Air Temp", new RampStrategy(74.0f, 1.0f, 1000)); - addStrategy("Return Air Temp", new RampStrategy(86.0f, 1.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); + addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); + addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 10.0f, 1000)); @@ -61,7 +62,7 @@ StandbyState::StandbyState() { addStrategy("Amps Fan 7", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 8", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 9", new RampStrategy(0.0f, 4.5f, 1000)); - + addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); } /** @@ -125,7 +126,7 @@ void StandbyState::enterState(Equipment* equipment) { for (const auto& desc : motorStatusDescriptions) { Modbus_Point* point = equipment->getModbus_Point(desc); if (point) { - point->setValue(1); + point->setValue(0); } }; diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 9490535..972a36c 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ const char *password = "52761492"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */ + IPAddress local_IP(192, 168, 0, 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. */ @@ -99,15 +99,15 @@ modbusMap mb_map[] = {IR, 50, 0, "Alarm Fan 7"}, {IR, 54, 0, "Alarm Fan 8"}, {IR, 58, 0, "Alarm Fan 9"}, - {IR, 27, 1, "Run Status Fan 1"}, // Send to PLC - {IR, 31, 1, "Run Status Fan 2"}, // Send to PLC - {IR, 35, 1, "Run Status Fan 3"}, // Send to PLC - {IR, 39, 1, "Run Status Fan 4"}, // Send to PLC - {IR, 43, 1, "Run Status Fan 5"}, // Send to PLC - {IR, 47, 1, "Run Status Fan 6"}, // Send to PLC - {IR, 51, 1, "Run Status Fan 7"}, // Send to PLC - {IR, 55, 1, "Run Status Fan 8"}, // Send to PLC - {IR, 59, 1, "Run Status Fan 9"}, // Send to PLC + {IR, 27, 0, "Run Status Fan 1"}, // Send to PLC + {IR, 31, 0, "Run Status Fan 2"}, // Send to PLC + {IR, 35, 0, "Run Status Fan 3"}, // Send to PLC + {IR, 39, 0, "Run Status Fan 4"}, // Send to PLC + {IR, 43, 0, "Run Status Fan 5"}, // Send to PLC + {IR, 47, 0, "Run Status Fan 6"}, // Send to PLC + {IR, 51, 0, "Run Status Fan 7"}, // Send to PLC + {IR, 55, 0, "Run Status Fan 8"}, // Send to PLC + {IR, 59, 0, "Run Status Fan 9"}, // Send to PLC {IR, 25, 0, "Speed Fan 1"}, {IR, 29, 0, "Speed Fan 2"}, {IR, 33, 0, "Speed Fan 3"}, @@ -135,7 +135,8 @@ modbusMap mb_map[] = {IR_FLOAT, 73, 0, "Amps Fan 6"}, {IR_FLOAT, 75, 0, "Amps Fan 7"}, {IR_FLOAT, 77, 0, "Amps Fan 8"}, - {IR_FLOAT, 79, 0, "Amps Fan 9"}, + {IR_FLOAT, 79, 0, "Amps Fan 9"}, + {IR_FLOAT, 99, 0, "CRAH Heartbeat"}, {HR_FLOAT, 13, 0, "Fan Speed Setpoint"}, // Receive signal from PLC {HR_FLOAT, 17, 0, "Supply Air Temp Setpoint"}, // Receive signal from PLC @@ -143,7 +144,8 @@ modbusMap mb_map[] = {HR_FLOAT, 23, 0, "Fan Max Speed"}, // Send to PLC {HR, 25, 0, "BMS Control Source"}, // Receive signal from PLC 0:Speed, 1:Room Temp {HR, 26, 2, "BMS Enable Source"}, // Receive signal from PLC 0:Keypad, 1:DI, 2:BMS - {HR, 99, 0, "CRAH Heartbeat"} // Placeholder - we don't have this from UMAS yet. Not used in logic yet. + {HR_FLOAT, 28, 0, "Fan Speed Feedback"}, + {HR_FLOAT, 99, 0, "PLC Heartbeat"}, // This will be seconds from PLC - if doesn't change for 15 seconds set BMS Enable Source to Local (0) }; //Size of modbus map used in FOR cycles, automatically calculated. From 245d01ed61576330898d92a6a3f5d2ca6522d1d2 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 1 Dec 2025 16:08:34 -0700 Subject: [PATCH 27/51] Added alarm setpoints Added alarm setpoint registers, adjusted individual fan speed --> RPM, ensured Fan Speed Feedback (40029) --> 0 in Standby/Fail mode. --- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 8 +++---- src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 19 ++++++++------- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 25 ++++++++++---------- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 19 ++++++++------- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 7 ++++++ 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index 8fdfcc1..c3e3522 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -107,16 +107,16 @@ void updateAlarms(Equipment* equipment){ // Note: The Common Alarm is not configured to annunciate with these analog low/high alarms. void updateAnalogs(Equipment* equipment){ if (equipment->getModbus_Point("RA Temp Low Alarm ON")->getValue() ==1){ - equipment->setModbus_Point("Return Air Temp", 68.0f); + equipment->setModbus_Point("Return Air Temp", 60.0f); } else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Temp", 104.0f); + equipment->setModbus_Point("Return Air Temp", 110.0f); } if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 15.0f); + equipment->setModbus_Point("Return Air Humidity", 5.0f); } else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 65.0f); + equipment->setModbus_Point("Return Air Humidity", 80.0f); } } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index ceeb819..b9d847b 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -43,15 +43,16 @@ FailState::FailState(const std::vector& activeAlarms) { addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); - addStrategy("Speed Fan 1", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 2", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 3", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 4", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 5", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 6", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 7", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 8", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 9", new RampStrategy(0.0f, 10.0f, 1000)); + addStrategy("Speed Fan 1", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 2", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 3", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 4", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 5", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 6", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 7", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 8", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 9", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Fan Speed Feedback", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Amps Fan 1", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 2", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 3", new RampStrategy(0.0f, 4.5f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index a1c8f16..eda823e 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -44,15 +44,15 @@ template<> RunningState::RunningState() { addStrategy("Fan Min Speed", new SingleValueStrategy(30.0f, 0.0f, 1000)); addStrategy("Fan Max Speed", new SingleValueStrategy(100.0f, 0.0f, 1000)); - addStrategy("Speed Fan 1", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 2", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 3", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 4", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 5", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 6", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 7", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 8", new RampStrategy(0.0f, 1.0f, 200)); - addStrategy("Speed Fan 9", new RampStrategy(0.0f, 1.0f, 200)); + addStrategy("Speed Fan 1", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 2", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 3", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 4", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 5", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 6", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 7", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 8", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 9", new RampStrategy(0.0f, 100.0f, 200)); addStrategy("Amps Fan 1", new RampStrategy(15.0f, 2.5f, 1000)); addStrategy("Amps Fan 2", new RampStrategy(15.0f, 2.5f, 1000)); addStrategy("Amps Fan 3", new RampStrategy(15.0f, 2.5f, 1000)); @@ -125,7 +125,8 @@ State* RunningState::update(Equipment* equipment) float BMS_Speed_Setpoint_Pct = BMS_Speed_Setpoint / 100.0f; float Fan_Min_Speed = getPointValue(equipment, "Fan Min Speed"); float Fan_Max_Speed = getPointValue(equipment, "Fan Max Speed"); - float Fan_Speed_Setpoint = BMS_Speed_Setpoint_Pct * (Fan_Max_Speed - Fan_Min_Speed) + Fan_Min_Speed; + float Fan_Nominal_Speed = 1900.0f; + float Fan_Speed_Setpoint = (BMS_Speed_Setpoint_Pct * (Fan_Max_Speed - Fan_Min_Speed) + Fan_Min_Speed)/100.0f * Fan_Nominal_Speed; for (int i = 0; i < 10; i++){ std::string pointName = "Speed Fan " + std::to_string(i); Strategy_Behavior* strat = getStrategy(pointName); @@ -133,10 +134,10 @@ State* RunningState::update(Equipment* equipment) RampStrategy* ramp = static_cast(strat); if (ramp){ if (BMS_Speed_Setpoint > 100){ - Fan_Speed_Setpoint = Fan_Max_Speed; + Fan_Speed_Setpoint = Fan_Max_Speed / 100.0f * Fan_Nominal_Speed; } else if (BMS_Speed_Setpoint < 0){ - Fan_Speed_Setpoint = Fan_Min_Speed; + Fan_Speed_Setpoint = Fan_Min_Speed / 100.0f * Fan_Nominal_Speed; } ramp->setTarget(Fan_Speed_Setpoint); } diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index 2b78791..90be569 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -44,15 +44,16 @@ StandbyState::StandbyState() { addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); - addStrategy("Speed Fan 1", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 2", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 3", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 4", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 5", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 6", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 7", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 8", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Speed Fan 9", new RampStrategy(0.0f, 10.0f, 1000)); + addStrategy("Speed Fan 1", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 2", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 3", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 4", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 5", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 6", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 7", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 8", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Speed Fan 9", new RampStrategy(0.0f, 300.0f, 1000)); + addStrategy("Fan Speed Feedback", new RampStrategy(0.0f, 10.0f, 1000)); addStrategy("Amps Fan 1", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 2", new RampStrategy(0.0f, 4.5f, 1000)); addStrategy("Amps Fan 3", new RampStrategy(0.0f, 4.5f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 972a36c..5829224 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -138,8 +138,15 @@ modbusMap mb_map[] = {IR_FLOAT, 79, 0, "Amps Fan 9"}, {IR_FLOAT, 99, 0, "CRAH Heartbeat"}, + {HR_FLOAT, 1, 0, "High Return Air Temp Setpoint"}, // default: 100, set locally on unit + {HR_FLOAT, 3, 0, "Low Return Air Temp Setpoint"}, // default: 72, set locally on unit + {HR_FLOAT, 5, 0, "High Supply Air Temp Setpoint"}, // default: 78, set locally on unit + {HR_FLOAT, 7, 0, "Low Return Air Temp Setpoint"}, // default: 72, set locally on unit + {HR_FLOAT, 9, 0, "High Return Humidity Setpoint"}, // default: 60, set locally on unit + {HR_FLOAT, 11, 0, "Low Return Humidity Setpoint"}, // default: 20, set locally on unit {HR_FLOAT, 13, 0, "Fan Speed Setpoint"}, // Receive signal from PLC {HR_FLOAT, 17, 0, "Supply Air Temp Setpoint"}, // Receive signal from PLC + {HR_FLOAT, 19, 0, "Return Air Temp Setpoint"}, // set locally on unit {HR_FLOAT, 21, 0, "Fan Min Speed"}, // Send to PLC {HR_FLOAT, 23, 0, "Fan Max Speed"}, // Send to PLC {HR, 25, 0, "BMS Control Source"}, // Receive signal from PLC 0:Speed, 1:Room Temp From 7bcbda8f38b4096581536d2a7eaa8a57b89aaead Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 2 Dec 2025 16:35:25 -0700 Subject: [PATCH 28/51] 40029, HB registers Updated Fan speed feedback calculation, Heartbeat registers --- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 42 +++++++++++--------- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 6 +-- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index eda823e..14a1b28 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -44,15 +44,15 @@ template<> RunningState::RunningState() { addStrategy("Fan Min Speed", new SingleValueStrategy(30.0f, 0.0f, 1000)); addStrategy("Fan Max Speed", new SingleValueStrategy(100.0f, 0.0f, 1000)); - addStrategy("Speed Fan 1", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 2", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 3", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 4", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 5", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 6", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 7", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 8", new RampStrategy(0.0f, 100.0f, 200)); - addStrategy("Speed Fan 9", new RampStrategy(0.0f, 100.0f, 200)); + addStrategy("Speed Fan 1", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 2", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 3", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 4", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 5", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 6", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 7", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 8", new RampStrategy(0.0f, 100.0f, 1000)); + addStrategy("Speed Fan 9", new RampStrategy(0.0f, 100.0f, 1000)); addStrategy("Amps Fan 1", new RampStrategy(15.0f, 2.5f, 1000)); addStrategy("Amps Fan 2", new RampStrategy(15.0f, 2.5f, 1000)); addStrategy("Amps Fan 3", new RampStrategy(15.0f, 2.5f, 1000)); @@ -73,11 +73,11 @@ RunningState::RunningState() { addStrategy("Operating Hours Fan 9", new TotalizerStrategy(1000)); addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.2f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan addStrategy("Return Air Humidity", new SawStrategy(25.0f, 40.0f, 1.1f, 1000)); - addStrategy("Return Air Temp", new SawStrategy(70.0f, 80.0f, 0.8f, 1000)); - addStrategy("Filter Differential Pressure", new SawStrategy(0.0f, 5.0f, 0.2f, 1000)); + addStrategy("Return Air Temp", new SawStrategy(84.0f, 87.0f, 0.2f, 1000)); + addStrategy("Filter Differential Pressure", new SawStrategy(0.1f, 5.1f, 0.2f, 1000)); addStrategy("CW Valve Position", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); // SAT must be greater than SAT Setpoint for this PID to work. addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); - addStrategy("Fan Speed Feedback", new RampStrategy(0.0f, 1.0f, 200)); + addStrategy("Fan Speed Feedback", new RampStrategy(0.0f, 2.0f, 200)); } /** @@ -121,12 +121,14 @@ State* RunningState::update(Equipment* equipment) // This will update the Fan Speed Setpoint dynamically while in run mode. Fan Speed Setpoint changed through Modscan. // This functioanlity matches the UMAS SOO specifically for how it calculates Speed Setpoint. - float BMS_Speed_Setpoint = getPointValue(equipment, "Fan Speed Setpoint"); - float BMS_Speed_Setpoint_Pct = BMS_Speed_Setpoint / 100.0f; float Fan_Min_Speed = getPointValue(equipment, "Fan Min Speed"); float Fan_Max_Speed = getPointValue(equipment, "Fan Max Speed"); float Fan_Nominal_Speed = 1900.0f; - float Fan_Speed_Setpoint = (BMS_Speed_Setpoint_Pct * (Fan_Max_Speed - Fan_Min_Speed) + Fan_Min_Speed)/100.0f * Fan_Nominal_Speed; + + float BMS_Speed_Setpoint = getPointValue(equipment, "Fan Speed Setpoint"); + float BMS_Speed_Setpoint_Pct = BMS_Speed_Setpoint / 100.0f; + float Fan_Speed_Setpoint = BMS_Speed_Setpoint_Pct * (Fan_Max_Speed - Fan_Min_Speed) + Fan_Min_Speed; + float Fan_Speed_Setpoint_RPM = Fan_Speed_Setpoint / 100.0f * Fan_Nominal_Speed; for (int i = 0; i < 10; i++){ std::string pointName = "Speed Fan " + std::to_string(i); Strategy_Behavior* strat = getStrategy(pointName); @@ -134,12 +136,14 @@ State* RunningState::update(Equipment* equipment) RampStrategy* ramp = static_cast(strat); if (ramp){ if (BMS_Speed_Setpoint > 100){ - Fan_Speed_Setpoint = Fan_Max_Speed / 100.0f * Fan_Nominal_Speed; + Fan_Speed_Setpoint = Fan_Max_Speed; + Fan_Speed_Setpoint_RPM = Fan_Max_Speed / 100.0f * Fan_Nominal_Speed; } else if (BMS_Speed_Setpoint < 0){ - Fan_Speed_Setpoint = Fan_Min_Speed / 100.0f * Fan_Nominal_Speed; + Fan_Speed_Setpoint = Fan_Min_Speed; + Fan_Speed_Setpoint_RPM = Fan_Min_Speed / 100.0f * Fan_Nominal_Speed; } - ramp->setTarget(Fan_Speed_Setpoint); + ramp->setTarget(Fan_Speed_Setpoint_RPM); } } } @@ -147,7 +151,7 @@ State* RunningState::update(Equipment* equipment) // Fan Speed Feedback dynamically ramp to Fan Speed Setpoint sent to Arduino Strategy_Behavior* speedFeedback = getStrategy("Fan Speed Feedback"); if (speedFeedback){ - static_cast(speedFeedback)->setTarget(BMS_Speed_Setpoint); + static_cast(speedFeedback)->setTarget(Fan_Speed_Setpoint); } // Apply any strategies defined for the standby state diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 5829224..307d76b 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -135,8 +135,7 @@ modbusMap mb_map[] = {IR_FLOAT, 73, 0, "Amps Fan 6"}, {IR_FLOAT, 75, 0, "Amps Fan 7"}, {IR_FLOAT, 77, 0, "Amps Fan 8"}, - {IR_FLOAT, 79, 0, "Amps Fan 9"}, - {IR_FLOAT, 99, 0, "CRAH Heartbeat"}, + {IR_FLOAT, 79, 0, "Amps Fan 9"}, {HR_FLOAT, 1, 0, "High Return Air Temp Setpoint"}, // default: 100, set locally on unit {HR_FLOAT, 3, 0, "Low Return Air Temp Setpoint"}, // default: 72, set locally on unit @@ -152,7 +151,8 @@ modbusMap mb_map[] = {HR, 25, 0, "BMS Control Source"}, // Receive signal from PLC 0:Speed, 1:Room Temp {HR, 26, 2, "BMS Enable Source"}, // Receive signal from PLC 0:Keypad, 1:DI, 2:BMS {HR_FLOAT, 28, 0, "Fan Speed Feedback"}, - {HR_FLOAT, 99, 0, "PLC Heartbeat"}, // This will be seconds from PLC - if doesn't change for 15 seconds set BMS Enable Source to Local (0) + {HR, 95, 0, "CRAH Heartbeat"}, + {HR, 96, 0, "BMS Heartbeat"}, // This will be seconds from PLC - if doesn't change for 15 seconds set BMS Enable Source to Local (0) }; //Size of modbus map used in FOR cycles, automatically calculated. From c5c2b28bf52ae865ded6a8f490215ae96ccee0e8 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 5 Dec 2025 15:43:17 -0700 Subject: [PATCH 29/51] com change com --- platformio.ini | 2 +- .../StateUtils.cpp | 42 +++++++++++++++++++ .../State_Running.cpp | 2 +- .../State_Standby.cpp | 2 +- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 11 ++++- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 2bec804..ec985dc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ default_envs = PHX3_CRAH_LIEBERT_80_SLAB_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM9 +upload_port = COM11 [common_env_options] framework = arduino diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index b50dc7f..5df8d4c 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -63,6 +63,48 @@ void updateAlarms(Equipment* equipment){ "Alarm Compressor 1B Overload ON", "Alarm Compressor 2B Overload ON" }; + Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); + Modbus_Point* supplyAirTemp = equipment -> getModbus_Point("Supply Air Temp"); + Modbus_Point* returnHumidity = equipment -> getModbus_Point("Return Humidity"); + //int supplyAirTemp = getPointValue(equipment, "Supply Air Temp"); + //int returnHumidity = getPointValue(equipment, "Return Humidity"); + + // Update Return Air Temp Alarms + if (returnAirTemp > equipment->getModbus_Point("Return Air Temp Alarm High SP")) { + equipment->setModbus_Point("Alarm High Return Air Temp", 1); + } + else if (returnAirTemp < equipment->getModbus_Point("Return Air Temp Alarm Low SP")) { + equipment->setModbus_Point("Alarm Low Return Air Temp", 1); + } + else{ + equipment->setModbus_Point("Alarm High Return Air Temp", 0); + equipment->setModbus_Point("Alarm Low Return Air Temp", 0); + } + + // Update Supply Air Temp Alarms + if (supplyAirTemp > equipment->getModbus_Point("Supply Air Temp Alarm High SP")) { + equipment->setModbus_Point("Alarm High Supply Temp", 1); + } + else if (supplyAirTemp < equipment->getModbus_Point("Supply Air Temp Alarm Low SP")) { + equipment->setModbus_Point("Alarm Low Supply Temp", 1); + } + else{ + equipment->setModbus_Point("Alarm High Supply Temp", 0); + equipment->setModbus_Point("Alarm Low Supply Temp", 0); + } + + // Update Return Humidity Alarms + if (returnHumidity > equipment->getModbus_Point("Return Humidity Alarm High SP")) { + equipment->setModbus_Point("Alarm High Return Humidity", 1); + } + else if (returnHumidity < equipment->getModbus_Point("Return Humidity Alarm Low SP")) { + equipment->setModbus_Point("AAlarm Low Return Humidity", 1); + } + else{ + equipment->setModbus_Point("Alarm High Return Humidity", 0); + equipment->setModbus_Point("Alarm Low Return Humidity", 0); + } + int numAlarms = 0; for (int i =0; i< alarmCommands.size() && i < alarmDescriptions.size(); ++i) { Modbus_Point* commandPoint = equipment->getModbus_Point(alarmCommands[i]); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp index 33c87c7..528183c 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp @@ -44,7 +44,7 @@ */ template<> RunningState::RunningState() { - addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 5.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(2.0f, 80.0f, 2.0f, 1000)); addStrategy("Return Air Temp", new SawStrategy(66.0f, 110.0f, 2.0f, 1000)); addStrategy("Supply Air Temp", new SawStrategy(68.0f, 86.0f, 1.0f, 1000)); addStrategy("Supply Air Flow", new SawStrategy(7.0f, 10.0f, 1.0f, 1000)); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp index 5db3e93..5468f3b 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp @@ -40,7 +40,7 @@ template<> StandbyState::StandbyState() { addStrategy("Fan Speed", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 5.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 2.0f, 1000)); addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); addStrategy("Supply Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 1000)); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index f547b18..cccecc6 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ const char *password = "52761492"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(192, 168, 1, 234); /**< @brief The static IP address for the device. */ + IPAddress local_IP(192, 168, 0, 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. */ @@ -68,7 +68,7 @@ modbusMap mb_map[] = {COIL, 6, 0, "Alarm Compressor 2A Overload ON"}, // For Arduino testing only {COIL, 7, 0, "Alarm Water Detected ON"}, // For Arduino testing only {COIL, 8, 0, "Alarm Standby Unit On ON"}, // For Arduino testing only - {COIL, 9, 0, "Alarm Room Sensor Failure ON"}, // For Arduino testing only + {COIL, 9, 0, "Alarm Room Sensor Failure ON"}, // For Arduino testing only {COIL, 10, 0, "Alarm Power Loss ON"}, // For Arduino testing only {COIL, 11, 0, "Alarm Clogged Filter ON"}, // For Arduino testing only {COIL, 12, 0, "Alarm Supply Sensor Failure ON"}, // For Arduino testing only @@ -144,8 +144,15 @@ modbusMap mb_map[] = {IR, 2050, 0, "Fluid Control Valve Position 1"}, {IR, 2051, 0, "Fluid Control Valve Position 2"}, + {HR_10x, 53, 60, "Return Humidity Alarm High SP"}, + {HR_10x, 54, 20, "Return Humidity Alarm Low SP"}, {HR, 732, 73, "Supply Air Temp Setpoint"}, + {HR_10x, 738, 100, "Return Air Temp Alarm High SP"}, + {HR_10x, 739, 72, "Return Air Temp Alarm Low SP"}, {HR, 753, 80, "Return Air Temp Setpoint"}, + {HR_10x, 754, 78, "Supply Air Temp Alarm High SP"}, + {HR_10x, 755, 72, "Supply Air Temp Alarm Low SP"}, + }; //Size of modbus map used in FOR cycles, automatically calculated. From 7145b047173b9c5907062d3180486e7b8bd2d423 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 08:37:09 -0700 Subject: [PATCH 30/51] updates --- .../StateUtils.cpp | 125 ++++++++++++------ .../StateUtils.h | 4 + .../State_Fail.cpp | 3 + .../State_Running.cpp | 9 ++ .../State_Standby.cpp | 11 ++ .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 23 +++- 6 files changed, 132 insertions(+), 43 deletions(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index 5df8d4c..cad0898 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -28,6 +28,90 @@ #include #endif +void updateReturnAirTempAlarms(Equipment* equipment){ + Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); + Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); + Modbus_Point* returnTempLowAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm Low SP"); + //Modbus_Point* returnTempHighAlarm = equipment->getModbus_Point("Alarm High Return Air Temp"); + //Modbus_Point* returnTempLowAlarm = equipment->getModbus_Point("Alarm Low Return Air Temp"); + + int RATemp = returnAirTemp->getValue(); + int RATempHighAlm = returnTempHighAlarmSP->getValue(); + int RATempLowAlm = returnTempLowAlarmSP->getValue(); + + equipment->setModbus_Point("RATemp Value", RATemp); + equipment->setModbus_Point("RATempHighAlm Value", RATempHighAlm); + equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); + + if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Return Air Temp", 1); + //returnTempHighAlarm->setValue(1); + } + else if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm Low Return Air Temp", 1); + //returnTempLowAlarm->setValue(1); + } + else{ + equipment->setModbus_Point("Alarm High Return Air Temp", 0); + equipment->setModbus_Point("Alarm Low Return Air Temp", 0); + //returnTempHighAlarm->setValue(0); + //returnTempLowAlarm->setValue(0); + } + +} + +void updateSupplyAirTempAlarms(Equipment* equipment){ + Modbus_Point* supplyAirTemp = equipment -> getModbus_Point("Supply Air Temp"); + Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); + Modbus_Point* supplyTempLowAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm Low SP"); + + int SATemp = supplyAirTemp->getValue(); + int SATempHighAlm = supplyTempHighAlarmSP->getValue(); + int SATempLowAlm = supplyTempLowAlarmSP->getValue(); + + equipment->setModbus_Point("SATemp Value", SATemp); + equipment->setModbus_Point("SATempHighAlm Value", SATempHighAlm); + equipment->setModbus_Point("SATempLowAlm Value", SATempLowAlm); + + + if (supplyAirTemp->getValue() > supplyTempHighAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Supply Temp", 1); + } + else if (supplyAirTemp->getValue() < supplyTempLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm Low Supply Temp", 1); + } + else{ + equipment->setModbus_Point("Alarm High Supply Temp", 0); + equipment->setModbus_Point("Alarm Low Supply Temp", 0); + } +} + +void updateReturnHumidityAlarms(Equipment* equipment){ + Modbus_Point* returnHumidity = equipment -> getModbus_Point("Return Humidity"); + Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); + Modbus_Point* returnHumLowAlarmSP = equipment->getModbus_Point("Return Humidity Alarm Low SP"); + + int RAHum = returnHumidity->getValue(); + int RAHumHighAlm = returnHumHighAlarmSP->getValue(); + int RAHumLowAlm = returnHumLowAlarmSP->getValue(); + + equipment->setModbus_Point("RATemp Value", RAHum); + equipment->setModbus_Point("RATempHighAlm Value", RAHumHighAlm); + equipment->setModbus_Point("RATempLowAlm Value", RAHumLowAlm); + + if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Return Humidity", 1); + } + else if (returnHumidity->getValue() < returnHumLowAlarmSP->getValue()) { + equipment->setModbus_Point("AAlarm Low Return Humidity", 1); + } + else{ + equipment->setModbus_Point("Alarm High Return Humidity", 0); + equipment->setModbus_Point("Alarm Low Return Humidity", 0); + } +} + + /** * @brief This function will update the Alarm status DI bits according to the Alarm Commands from Coils (Modscan) * It will also update the Common Alarm: if any alarm is active, the Common alarm will also be active. @@ -62,48 +146,7 @@ void updateAlarms(Equipment* equipment){ "Common Alarm ON", "Alarm Pump Failure ON", "Alarm Comm Loss Condenser 1 ON", "Alarm Comm Loss Condenser 2 ON", "Alarm Compressor 1B Overload ON", "Alarm Compressor 2B Overload ON" }; - - Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); - Modbus_Point* supplyAirTemp = equipment -> getModbus_Point("Supply Air Temp"); - Modbus_Point* returnHumidity = equipment -> getModbus_Point("Return Humidity"); - //int supplyAirTemp = getPointValue(equipment, "Supply Air Temp"); - //int returnHumidity = getPointValue(equipment, "Return Humidity"); - // Update Return Air Temp Alarms - if (returnAirTemp > equipment->getModbus_Point("Return Air Temp Alarm High SP")) { - equipment->setModbus_Point("Alarm High Return Air Temp", 1); - } - else if (returnAirTemp < equipment->getModbus_Point("Return Air Temp Alarm Low SP")) { - equipment->setModbus_Point("Alarm Low Return Air Temp", 1); - } - else{ - equipment->setModbus_Point("Alarm High Return Air Temp", 0); - equipment->setModbus_Point("Alarm Low Return Air Temp", 0); - } - - // Update Supply Air Temp Alarms - if (supplyAirTemp > equipment->getModbus_Point("Supply Air Temp Alarm High SP")) { - equipment->setModbus_Point("Alarm High Supply Temp", 1); - } - else if (supplyAirTemp < equipment->getModbus_Point("Supply Air Temp Alarm Low SP")) { - equipment->setModbus_Point("Alarm Low Supply Temp", 1); - } - else{ - equipment->setModbus_Point("Alarm High Supply Temp", 0); - equipment->setModbus_Point("Alarm Low Supply Temp", 0); - } - - // Update Return Humidity Alarms - if (returnHumidity > equipment->getModbus_Point("Return Humidity Alarm High SP")) { - equipment->setModbus_Point("Alarm High Return Humidity", 1); - } - else if (returnHumidity < equipment->getModbus_Point("Return Humidity Alarm Low SP")) { - equipment->setModbus_Point("AAlarm Low Return Humidity", 1); - } - else{ - equipment->setModbus_Point("Alarm High Return Humidity", 0); - equipment->setModbus_Point("Alarm Low Return Humidity", 0); - } int numAlarms = 0; for (int i =0; i< alarmCommands.size() && i < alarmDescriptions.size(); ++i) { diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h index e2c1196..359c2fa 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h @@ -28,6 +28,10 @@ template class State; +void updateReturnAirTempAlarms(Equipment* equipment); +void updateSupplyAirTempAlarms(Equipment* equipment); +void updateReturnHumidityAlarms(Equipment* equipment); + /** * @brief Checks common alarms (non-fail alarms) and updates the Common Alarm Modbus point. * @param equipment Pointer to the Equipment instance. diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp index 888d1b4..a689c30 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp @@ -62,6 +62,9 @@ State* FailState::update(Equipment* equipment) { Serial.println("Fail update function"); setPointValue(equipment, "System On/Off Control", 0); // my programming logic: when clear fault, should be sent to Standby Mode + updateReturnAirTempAlarms(equipment); + updateSupplyAirTempAlarms(equipment); + updateReturnHumidityAlarms(equipment); updateAlarms(equipment); updateDehumidifier(equipment); // Dehumidifier mode can be toggled while in FailState (for ease of Ignition HMI verification) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp index 528183c..9d37f4c 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp @@ -47,6 +47,11 @@ RunningState::RunningState() { addStrategy("Return Humidity", new SawStrategy(2.0f, 80.0f, 2.0f, 1000)); addStrategy("Return Air Temp", new SawStrategy(66.0f, 110.0f, 2.0f, 1000)); addStrategy("Supply Air Temp", new SawStrategy(68.0f, 86.0f, 1.0f, 1000)); + + //addStrategy("Return Humidity", new SingleValueStrategy(10.0f, 0.0f, 1000)); + //addStrategy("Return Air Temp", new SingleValueStrategy(50.0f, 0.0f, 1000)); + //addStrategy("Supply Air Temp", new SingleValueStrategy(60.0f, 0.0f, 1000)); + addStrategy("Supply Air Flow", new SawStrategy(7.0f, 10.0f, 1.0f, 1000)); addStrategy("Fan Speed", new PIDStrategy("Return Air Temp Setpoint", 1000, "Return Air Temp")); addStrategy("Fluid Control Valve Position 1", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); @@ -72,6 +77,10 @@ template<> State* RunningState::update(Equipment* equipment) { Serial.println("Running update function"); + updateReturnAirTempAlarms(equipment); + updateSupplyAirTempAlarms(equipment); + updateReturnHumidityAlarms(equipment); + updateAlarms(equipment); updateDehumidifier(equipment); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp index 5468f3b..e844b29 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp @@ -46,6 +46,13 @@ StandbyState::StandbyState() { addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 1000)); addStrategy("Fluid Control Valve Position 1", new RampStrategy(0.0f, 5.0f, 1000)); addStrategy("Fluid Control Valve Position 2", new RampStrategy(0.0f, 5.0f, 1000)); + + addStrategy("Return Humidity Alarm High SP", new SingleValueStrategy(60.0f, 0.0f, 1000)); + addStrategy("Return Humidity Alarm Low SP", new SingleValueStrategy(20.0f, 0.0f, 1000)); + addStrategy("Return Air Temp Alarm High SP", new SingleValueStrategy(100.0f, 0.0f, 1000)); + addStrategy("Return Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 0.0f, 1000)); + addStrategy("Supply Air Temp Alarm High SP", new SingleValueStrategy(78.0f, 1.0f, 1000)); + addStrategy("Supply Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 1.0f, 1000)); } /** @@ -67,6 +74,10 @@ State* StandbyState::update(Equipment* equipment) // STATE control, add conditions if change to a different state is needed Serial.println("Standby update function"); + updateReturnAirTempAlarms(equipment); + updateSupplyAirTempAlarms(equipment); + updateReturnHumidityAlarms(equipment); + updateAlarms(equipment); updateDehumidifier(equipment); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index cccecc6..5e96ab1 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -93,6 +93,9 @@ modbusMap mb_map[] = {COIL, 30, 0, "Alarm Compressor 1B Overload ON"}, // For Arduino testing only {COIL, 31, 0, "Alarm Compressor 2B Overload ON"}, // For Arduino testing only + //{COIL, 32, 0, "Return Humidity LOW"}, // For Arduino testing only + //{COIL, 33, 0, "Return Humidity HIGH"}, // For Arduino testing only + {DI, 24, 0, "Supply Fan Status"}, {DI, 25, 0, "Cooling Status"}, {DI, 26, 0, "Free Cooling Status"}, @@ -146,12 +149,28 @@ modbusMap mb_map[] = {HR_10x, 53, 60, "Return Humidity Alarm High SP"}, {HR_10x, 54, 20, "Return Humidity Alarm Low SP"}, + {HR, 56, 0, "RAHum Value"}, + {HR, 57, 0, "RAHumHighAlm Value"}, + {HR, 58, 0, "RAHumLowAlm Value"}, + + {HR, 732, 73, "Supply Air Temp Setpoint"}, - {HR_10x, 738, 100, "Return Air Temp Alarm High SP"}, - {HR_10x, 739, 72, "Return Air Temp Alarm Low SP"}, + + + {HR_10x, 738, 0, "Return Air Temp Alarm High SP"}, + {HR_10x, 739, 0, "Return Air Temp Alarm Low SP"}, + {HR, 740, 0, "RATemp Value"}, + {HR, 741, 0, "RATempHighAlm Value"}, + {HR, 742, 0, "RATempLowAlm Value"}, + + {HR, 753, 80, "Return Air Temp Setpoint"}, {HR_10x, 754, 78, "Supply Air Temp Alarm High SP"}, {HR_10x, 755, 72, "Supply Air Temp Alarm Low SP"}, + {HR, 740, 0, "SATemp Value"}, + {HR, 741, 0, "SATempHighAlm Value"}, + {HR, 742, 0, "SATempLowAlm Value"}, + }; //Size of modbus map used in FOR cycles, automatically calculated. From b25048f0e6e4340e0b88752555c6cf08d41fb92a Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 17:45:30 -0600 Subject: [PATCH 31/51] change IP address for Schertz testing --- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 307d76b..93fc80a 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ - const char *password = "52761492"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(192, 168, 0, 234); /**< @brief The static IP address for the device. */ - IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 10); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; From 6dae38f8a5a4688d8ab6de6cfc46f7bda8808bbb Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 18:23:06 -0600 Subject: [PATCH 32/51] WIP common alarm --- .../StateUtils.cpp | 23 +++++++++++++++---- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 20 ++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index cad0898..fa0e4ff 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -44,6 +44,7 @@ void updateReturnAirTempAlarms(Equipment* equipment){ equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Return Air Temp", 1); equipment->setModbus_Point("Alarm High Return Air Temp", 1); //returnTempHighAlarm->setValue(1); } @@ -95,15 +96,15 @@ void updateReturnHumidityAlarms(Equipment* equipment){ int RAHumHighAlm = returnHumHighAlarmSP->getValue(); int RAHumLowAlm = returnHumLowAlarmSP->getValue(); - equipment->setModbus_Point("RATemp Value", RAHum); - equipment->setModbus_Point("RATempHighAlm Value", RAHumHighAlm); - equipment->setModbus_Point("RATempLowAlm Value", RAHumLowAlm); + equipment->setModbus_Point("RAHum Value", RAHum); + equipment->setModbus_Point("RAHumHighAlm Value", RAHumHighAlm); + equipment->setModbus_Point("RAHumLowAlm Value", RAHumLowAlm); if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Humidity", 1); } else if (returnHumidity->getValue() < returnHumLowAlarmSP->getValue()) { - equipment->setModbus_Point("AAlarm Low Return Humidity", 1); + equipment->setModbus_Point("Alarm Low Return Humidity", 1); } else{ equipment->setModbus_Point("Alarm High Return Humidity", 0); @@ -146,8 +147,14 @@ void updateAlarms(Equipment* equipment){ "Common Alarm ON", "Alarm Pump Failure ON", "Alarm Comm Loss Condenser 1 ON", "Alarm Comm Loss Condenser 2 ON", "Alarm Compressor 1B Overload ON", "Alarm Compressor 2B Overload ON" }; + + const std::vector alarmAnalogs = { + "Alarm High Return Air Temp", "Alarm Low Return Air Temp", "Alarm High Return Humidity", "Alarm Low Return Humidity", + "Alarm High Supply Temp", "Alarm Low Supply Temp" + }; + // If any Alarm Commands = 1, set the appropriate Alarm = 1 and increment counter for number of active alarms int numAlarms = 0; for (int i =0; i< alarmCommands.size() && i < alarmDescriptions.size(); ++i) { Modbus_Point* commandPoint = equipment->getModbus_Point(alarmCommands[i]); @@ -157,6 +164,14 @@ void updateAlarms(Equipment* equipment){ if (alarmPoint->getValue() == 1) numAlarms++; } } + // If any of the analog alarms = 1, increment counter for number of active alarms + for (int j = 0; j* alarmAnalogPoint = equipment->getModbus_Point(alarmAnalogs[j]); + if (alarmAnalogPoint) { + if (alarmAnalogPoint->getValue() == 1) numAlarms++; + } + } + // If any alarms are active, set the Common Alarm = 1, else Common Alarm = 0. if (numAlarms >= 1) equipment->setModbus_Point("Common Alarm", 1); else equipment->setModbus_Point("Common Alarm", 0); } diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index 5e96ab1..e9e6797 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #include - const char *ssid = "TP-Link_D91A"; /**< @brief The SSID of the WiFi network. */ - const char *password = "52761492"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(192, 168, 0, 234); /**< @brief The static IP address for the device. */ - IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */ + const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ + const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 32, 11); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; @@ -159,17 +159,17 @@ modbusMap mb_map[] = {HR_10x, 738, 0, "Return Air Temp Alarm High SP"}, {HR_10x, 739, 0, "Return Air Temp Alarm Low SP"}, - {HR, 740, 0, "RATemp Value"}, - {HR, 741, 0, "RATempHighAlm Value"}, - {HR, 742, 0, "RATempLowAlm Value"}, + {HR, 741, 0, "RATemp Value"}, + {HR, 742, 0, "RATempHighAlm Value"}, + {HR, 743, 0, "RATempLowAlm Value"}, {HR, 753, 80, "Return Air Temp Setpoint"}, {HR_10x, 754, 78, "Supply Air Temp Alarm High SP"}, {HR_10x, 755, 72, "Supply Air Temp Alarm Low SP"}, - {HR, 740, 0, "SATemp Value"}, - {HR, 741, 0, "SATempHighAlm Value"}, - {HR, 742, 0, "SATempLowAlm Value"}, + {HR, 757, 0, "SATemp Value"}, + {HR, 758, 0, "SATempHighAlm Value"}, + {HR, 759, 0, "SATempLowAlm Value"}, }; From 75c4b0169e52aeb59ed450242c48975e346af7d8 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 20:17:44 -0600 Subject: [PATCH 33/51] Return Humidity, Temp, Supply Temp Added capability for RA Temp, SA Temp, RA Humidity to alarm (register) using Coils (Low, Normal, High), and adjusted Common Alarm code accordingly. --- .../StateUtils.cpp | 62 +++++++++++++++++-- .../StateUtils.h | 1 + .../State_Fail.cpp | 7 ++- .../State_Running.cpp | 7 ++- .../State_Standby.cpp | 21 ++++--- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 33 ++++++---- 6 files changed, 97 insertions(+), 34 deletions(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index fa0e4ff..930247a 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -28,6 +28,54 @@ #include #endif +void updateAnalogs(Equipment* equipment){ + if (equipment->getModbus_Point("RA Temp NORMAL")->getValue()==1){ + equipment->setModbus_Point("Return Air Temp", 84.0f); + equipment->setModbus_Point("RA Temp Low Alarm ON", 0); + equipment->setModbus_Point("RA Temp High Alarm ON", 0); + equipment->setModbus_Point("RA Temp NORMAL", 0); + } + else if (equipment->getModbus_Point("RA Temp Low Alarm ON")->getValue() ==1){ + equipment->setModbus_Point("Return Air Temp", 60.0f); + equipment->setModbus_Point("RA Temp High Alarm ON", 0); + } + else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Return Air Temp", 110.0f); + equipment->setModbus_Point("RA Temp Low Alarm ON", 0); + } + + if (equipment->getModbus_Point("RA Humidity NORMAL")->getValue()==1){ + equipment->setModbus_Point("Return Humidity", 25.0f); + equipment->setModbus_Point("RA Humidity Low Alarm ON", 0); + equipment->setModbus_Point("RA Humidity High Alarm ON", 0); + equipment->setModbus_Point("RA Humidity NORMAL", 0); + } + else if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Return Humidity", 5.0f); + equipment->setModbus_Point("RA Humidity High Alarm ON", 0); + } + else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Return Humidity", 80.0f); + equipment->setModbus_Point("RA Humidity Low Alarm ON", 0); + } + + if (equipment->getModbus_Point("SA Temp NORMAL")->getValue()==1){ + equipment->setModbus_Point("Supply Air Temp", 76.0f); + equipment->setModbus_Point("SA Temp Low Alarm ON", 0); + equipment->setModbus_Point("SA Temp High Alarm ON", 0); + equipment->setModbus_Point("SA Temp NORMAL", 0); + } + else if (equipment->getModbus_Point("SA Temp Low Alarm ON")->getValue() ==1){ + equipment->setModbus_Point("Supply Air Temp", 60.0f); + equipment->setModbus_Point("SA Temp High Alarm ON", 0); + } + else if (equipment->getModbus_Point("SA Temp High Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Supply Air Temp", 90.0f); + equipment->setModbus_Point("SA Temp Low Alarm ON", 0); + } + +} + void updateReturnAirTempAlarms(Equipment* equipment){ Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); @@ -44,12 +92,13 @@ void updateReturnAirTempAlarms(Equipment* equipment){ equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { - equipment->setModbus_Point("Alarm High Return Air Temp", 1); - equipment->setModbus_Point("Alarm High Return Air Temp", 1); + equipment->setModbus_Point("Alarm Low Return Air Temp", 1); + equipment->setModbus_Point("Alarm High Return Air Temp", 0); //returnTempHighAlarm->setValue(1); } - else if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { - equipment->setModbus_Point("Alarm Low Return Air Temp", 1); + else if (returnAirTemp->getValue() > returnTempHighAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Return Air Temp", 1); + equipment->setModbus_Point("Alarm Low Return Air Temp", 0); //returnTempLowAlarm->setValue(1); } else{ @@ -77,9 +126,11 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ if (supplyAirTemp->getValue() > supplyTempHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Supply Temp", 1); + equipment->setModbus_Point("Alarm Low Supply Temp", 0); } else if (supplyAirTemp->getValue() < supplyTempLowAlarmSP->getValue()) { equipment->setModbus_Point("Alarm Low Supply Temp", 1); + equipment->setModbus_Point("Alarm High Supply Temp", 0); } else{ equipment->setModbus_Point("Alarm High Supply Temp", 0); @@ -102,9 +153,11 @@ void updateReturnHumidityAlarms(Equipment* equipment){ if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Humidity", 1); + equipment->setModbus_Point("Alarm Low Return Humidity", 0); } else if (returnHumidity->getValue() < returnHumLowAlarmSP->getValue()) { equipment->setModbus_Point("Alarm Low Return Humidity", 1); + equipment->setModbus_Point("Alarm High Return Humidity", 0); } else{ equipment->setModbus_Point("Alarm High Return Humidity", 0); @@ -153,7 +206,6 @@ void updateAlarms(Equipment* equipment){ "Alarm High Supply Temp", "Alarm Low Supply Temp" }; - // If any Alarm Commands = 1, set the appropriate Alarm = 1 and increment counter for number of active alarms int numAlarms = 0; for (int i =0; i< alarmCommands.size() && i < alarmDescriptions.size(); ++i) { diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h index 359c2fa..861ff6d 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.h @@ -28,6 +28,7 @@ template class State; +void updateAnalogs(Equipment* equipment); void updateReturnAirTempAlarms(Equipment* equipment); void updateSupplyAirTempAlarms(Equipment* equipment); void updateReturnHumidityAlarms(Equipment* equipment); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp index a689c30..68a36fb 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Fail.cpp @@ -34,9 +34,9 @@ template<> FailState::FailState(const std::vector& activeAlarms) { addStrategy("Fan Speed", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 5.0f, 1000)); - addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Supply Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(25.0f, 35.0f, 1.0f, 2000)); + addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 3000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(76.0f, 1.0f, 3000)); addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 1000)); addStrategy("Fluid Control Valve Position 1", new RampStrategy(0.0f, 5.0f, 1000)); addStrategy("Fluid Control Valve Position 2", new RampStrategy(0.0f, 5.0f, 1000)); @@ -62,6 +62,7 @@ State* FailState::update(Equipment* equipment) { Serial.println("Fail update function"); setPointValue(equipment, "System On/Off Control", 0); // my programming logic: when clear fault, should be sent to Standby Mode + updateAnalogs(equipment); updateReturnAirTempAlarms(equipment); updateSupplyAirTempAlarms(equipment); updateReturnHumidityAlarms(equipment); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp index 9d37f4c..b7a5117 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp @@ -44,9 +44,9 @@ */ template<> RunningState::RunningState() { - addStrategy("Return Humidity", new SawStrategy(2.0f, 80.0f, 2.0f, 1000)); - addStrategy("Return Air Temp", new SawStrategy(66.0f, 110.0f, 2.0f, 1000)); - addStrategy("Supply Air Temp", new SawStrategy(68.0f, 86.0f, 1.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(25.0f, 35.0f, 1.0f, 2000)); + addStrategy("Return Air Temp", new SawStrategy(78.0f, 88.0f, 1.0f, 3000)); + addStrategy("Supply Air Temp", new SawStrategy(73.0f, 77.0f, 1.0f, 5000)); //addStrategy("Return Humidity", new SingleValueStrategy(10.0f, 0.0f, 1000)); //addStrategy("Return Air Temp", new SingleValueStrategy(50.0f, 0.0f, 1000)); @@ -77,6 +77,7 @@ template<> State* RunningState::update(Equipment* equipment) { Serial.println("Running update function"); + updateAnalogs(equipment); updateReturnAirTempAlarms(equipment); updateSupplyAirTempAlarms(equipment); updateReturnHumidityAlarms(equipment); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp index e844b29..982a353 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp @@ -40,19 +40,19 @@ template<> StandbyState::StandbyState() { addStrategy("Fan Speed", new RampStrategy(0.0f, 10.0f, 1000)); - addStrategy("Return Humidity", new SawStrategy(0.0f, 80.0f, 2.0f, 1000)); - addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Supply Air Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 1000)); + addStrategy("Return Humidity", new SawStrategy(25.0f, 35.0f, 1.0f, 2000)); + addStrategy("Return Air Temp", new SingleValueStrategy(80.0f, 1.0f, 3000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(76.0f, 1.0f, 3000)); + addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 5000)); addStrategy("Fluid Control Valve Position 1", new RampStrategy(0.0f, 5.0f, 1000)); addStrategy("Fluid Control Valve Position 2", new RampStrategy(0.0f, 5.0f, 1000)); - addStrategy("Return Humidity Alarm High SP", new SingleValueStrategy(60.0f, 0.0f, 1000)); - addStrategy("Return Humidity Alarm Low SP", new SingleValueStrategy(20.0f, 0.0f, 1000)); - addStrategy("Return Air Temp Alarm High SP", new SingleValueStrategy(100.0f, 0.0f, 1000)); - addStrategy("Return Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 0.0f, 1000)); - addStrategy("Supply Air Temp Alarm High SP", new SingleValueStrategy(78.0f, 1.0f, 1000)); - addStrategy("Supply Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 1.0f, 1000)); + //addStrategy("Return Humidity Alarm High SP", new SingleValueStrategy(60.0f, 0.0f, 1000)); + //addStrategy("Return Humidity Alarm Low SP", new SingleValueStrategy(20.0f, 0.0f, 1000)); + //addStrategy("Return Air Temp Alarm High SP", new SingleValueStrategy(100.0f, 0.0f, 1000)); + //addStrategy("Return Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 0.0f, 1000)); + //addStrategy("Supply Air Temp Alarm High SP", new SingleValueStrategy(78.0f, 0.0f, 1000)); + //addStrategy("Supply Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 0.0f, 1000)); } /** @@ -74,6 +74,7 @@ State* StandbyState::update(Equipment* equipment) // STATE control, add conditions if change to a different state is needed Serial.println("Standby update function"); + updateAnalogs(equipment); updateReturnAirTempAlarms(equipment); updateSupplyAirTempAlarms(equipment); updateReturnHumidityAlarms(equipment); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index e9e6797..230f994 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -93,8 +93,17 @@ modbusMap mb_map[] = {COIL, 30, 0, "Alarm Compressor 1B Overload ON"}, // For Arduino testing only {COIL, 31, 0, "Alarm Compressor 2B Overload ON"}, // For Arduino testing only - //{COIL, 32, 0, "Return Humidity LOW"}, // For Arduino testing only - //{COIL, 33, 0, "Return Humidity HIGH"}, // For Arduino testing only + {COIL, 32, 0, "RA Temp Low Alarm ON"}, // For Arduino testing only - sets RA Temp = 60 + {COIL, 33, 0, "RA Temp NORMAL"}, // For Arduino testing only - sets RA Temp = 84 + {COIL, 34, 0, "RA Temp High Alarm ON"}, // For Arduino testing only - sets RA Temp = 110 + + {COIL, 35, 0, "RA Humidity Low Alarm ON"}, // For Arduino testing only - sets RA Humidity = 5 + {COIL, 36, 0, "RA Humidity NORMAL"}, // For Arduino testing only - sets RA Humidity = 25 + {COIL, 37, 0, "RA Humidity High Alarm ON"}, // For Arduino testing only - sets RA Humidity = 80 + + {COIL, 38, 0, "SA Temp Low Alarm ON"}, // For Arduino testing only - sets SA Temp = 60 + {COIL, 39, 0, "SA Temp NORMAL"}, // For Arduino testing only - sets SA Temp = 76 + {COIL, 40, 0, "SA Temp High Alarm ON"}, // For Arduino testing only - sets SA Temp = 90 {DI, 24, 0, "Supply Fan Status"}, {DI, 25, 0, "Cooling Status"}, @@ -140,33 +149,31 @@ modbusMap mb_map[] = {IR, 99, 0, "Unit Status"}, // 0:off, 1:on, 2:standby {IR, 102, 0, "Fan Speed"}, - {IR_10x, 129, 0, "Return Humidity"}, - {IR_10x, 742, 0, "Return Air Temp"}, - {IR_10x, 743, 0, "Supply Air Temp"}, + {IR_10x, 129, 250, "Return Humidity"}, + {IR_10x, 742, 840, "Return Air Temp"}, + {IR_10x, 743, 760, "Supply Air Temp"}, {IR, 1465, 0, "Supply Air Flow"}, {IR, 2050, 0, "Fluid Control Valve Position 1"}, {IR, 2051, 0, "Fluid Control Valve Position 2"}, - {HR_10x, 53, 60, "Return Humidity Alarm High SP"}, - {HR_10x, 54, 20, "Return Humidity Alarm Low SP"}, + {HR_10x, 53, 600, "Return Humidity Alarm High SP"}, + {HR_10x, 54, 200, "Return Humidity Alarm Low SP"}, {HR, 56, 0, "RAHum Value"}, {HR, 57, 0, "RAHumHighAlm Value"}, {HR, 58, 0, "RAHumLowAlm Value"}, - {HR, 732, 73, "Supply Air Temp Setpoint"}, - - {HR_10x, 738, 0, "Return Air Temp Alarm High SP"}, - {HR_10x, 739, 0, "Return Air Temp Alarm Low SP"}, + {HR_10x, 738, 1000, "Return Air Temp Alarm High SP"}, + {HR_10x, 739, 720, "Return Air Temp Alarm Low SP"}, {HR, 741, 0, "RATemp Value"}, {HR, 742, 0, "RATempHighAlm Value"}, {HR, 743, 0, "RATempLowAlm Value"}, {HR, 753, 80, "Return Air Temp Setpoint"}, - {HR_10x, 754, 78, "Supply Air Temp Alarm High SP"}, - {HR_10x, 755, 72, "Supply Air Temp Alarm Low SP"}, + {HR_10x, 754, 780, "Supply Air Temp Alarm High SP"}, + {HR_10x, 755, 720, "Supply Air Temp Alarm Low SP"}, {HR, 757, 0, "SATemp Value"}, {HR, 758, 0, "SATempHighAlm Value"}, {HR, 759, 0, "SATempLowAlm Value"}, From 9adcdd8a39a0949936ed30dcf13d1d5e0e669131 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 21:02:12 -0600 Subject: [PATCH 34/51] Updated RA Temp, SA Temp, RA Humidity Alarms Added capability to set RA Temp, SA Temp, RA Humidity to Low, Normal, High range for alarms testing (added alarm registers). Updated Common alarm code appropriately. --- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 196 ++++++++++++++++--- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h | 12 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 5 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 5 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 11 +- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 65 +++--- 6 files changed, 225 insertions(+), 69 deletions(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index c3e3522..0d661c2 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -53,6 +53,158 @@ void updateControlMode(Equipment* equipment){ equipment->setModbus_Point("Control Mode Selected", Control_Mode_Selected); } +/** + * @brief The purpose of this function is for testing the RA Temp, SA Temp, and RA Humidity alarms (Ignition HMI display) + * User will manually set Alarms through Modscan coils, which will change RA Temp or RA Humidity accordingly. + * The RA Temp alarm limits (reference Ignition UDT) are 72, 100. + * The SA Temp alarm limits (reference Ignition UDT) are 72, 78. + * The RA Humidity alarm limits (reference Ignition UDT) are 20, 60. + * If an associated alarm coil is not active, the analog values are set to a safe, un-alarmed value. + * + * This is a function used in the update() of the Running State. + * +*/ + +void updateAnalogs(Equipment* equipment){ + if (equipment->getModbus_Point("RA Temp NORMAL")->getValue()==1){ + equipment->setModbus_Point("Return Air Temp", 86.0f); + equipment->setModbus_Point("RA Temp Low Alarm ON", 0); + equipment->setModbus_Point("RA Temp High Alarm ON", 0); + equipment->setModbus_Point("RA Temp NORMAL", 0); + } + else if (equipment->getModbus_Point("RA Temp Low Alarm ON")->getValue() ==1){ + equipment->setModbus_Point("Return Air Temp", 62.0f); + equipment->setModbus_Point("RA Temp High Alarm ON", 0); + } + else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Return Air Temp", 106.0f); + equipment->setModbus_Point("RA Temp Low Alarm ON", 0); + } + + if (equipment->getModbus_Point("RA Humidity NORMAL")->getValue()==1){ + equipment->setModbus_Point("Return Air Humidity", 25.0f); + equipment->setModbus_Point("RA Humidity Low Alarm ON", 0); + equipment->setModbus_Point("RA Humidity High Alarm ON", 0); + equipment->setModbus_Point("RA Humidity NORMAL", 0); + } + else if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Return Air Humidity", 6.0f); + equipment->setModbus_Point("RA Humidity High Alarm ON", 0); + } + else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Return Air Humidity", 80.0f); + equipment->setModbus_Point("RA Humidity Low Alarm ON", 0); + } + + if (equipment->getModbus_Point("SA Temp NORMAL")->getValue()==1){ + equipment->setModbus_Point("Supply Air Temp", 76.0f); + equipment->setModbus_Point("SA Temp Low Alarm ON", 0); + equipment->setModbus_Point("SA Temp High Alarm ON", 0); + equipment->setModbus_Point("SA Temp NORMAL", 0); + } + else if (equipment->getModbus_Point("SA Temp Low Alarm ON")->getValue() ==1){ + equipment->setModbus_Point("Supply Air Temp", 60.0f); + equipment->setModbus_Point("SA Temp High Alarm ON", 0); + } + else if (equipment->getModbus_Point("SA Temp High Alarm ON")->getValue()==1){ + equipment->setModbus_Point("Supply Air Temp", 90.0f); + equipment->setModbus_Point("SA Temp Low Alarm ON", 0); + } + +} + +void updateReturnAirTempAlarms(Equipment* equipment){ + Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); + Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); + Modbus_Point* returnTempLowAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm Low SP"); + //Modbus_Point* returnTempHighAlarm = equipment->getModbus_Point("Alarm High Return Air Temp"); + //Modbus_Point* returnTempLowAlarm = equipment->getModbus_Point("Alarm Low Return Air Temp"); + + //int RATemp = returnAirTemp->getValue(); + //int RATempHighAlm = returnTempHighAlarmSP->getValue(); + //int RATempLowAlm = returnTempLowAlarmSP->getValue(); + + //equipment->setModbus_Point("RATemp Value", RATemp); + //equipment->setModbus_Point("RATempHighAlm Value", RATempHighAlm); + //equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); + + if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm Low Return Air Temp", 1); + equipment->setModbus_Point("Alarm High Return Air Temp", 0); + //returnTempHighAlarm->setValue(1); + } + else if (returnAirTemp->getValue() > returnTempHighAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Return Air Temp", 1); + equipment->setModbus_Point("Alarm Low Return Air Temp", 0); + //returnTempLowAlarm->setValue(1); + } + else{ + equipment->setModbus_Point("Alarm High Return Air Temp", 0); + equipment->setModbus_Point("Alarm Low Return Air Temp", 0); + //returnTempHighAlarm->setValue(0); + //returnTempLowAlarm->setValue(0); + } + +} + +void updateSupplyAirTempAlarms(Equipment* equipment){ + Modbus_Point* supplyAirTemp = equipment -> getModbus_Point("Supply Air Temp"); + Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); + Modbus_Point* supplyTempLowAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm Low SP"); + + /** + int SATemp = supplyAirTemp->getValue(); + int SATempHighAlm = supplyTempHighAlarmSP->getValue(); + int SATempLowAlm = supplyTempLowAlarmSP->getValue(); + + equipment->setModbus_Point("SATemp Value", SATemp); + equipment->setModbus_Point("SATempHighAlm Value", SATempHighAlm); + equipment->setModbus_Point("SATempLowAlm Value", SATempLowAlm); + */ + + if (supplyAirTemp->getValue() > supplyTempHighAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Supply Temp", 1); + equipment->setModbus_Point("Alarm Low Supply Temp", 0); + } + else if (supplyAirTemp->getValue() < supplyTempLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm Low Supply Temp", 1); + equipment->setModbus_Point("Alarm High Supply Temp", 0); + } + else{ + equipment->setModbus_Point("Alarm High Supply Temp", 0); + equipment->setModbus_Point("Alarm Low Supply Temp", 0); + } +} + +void updateReturnHumidityAlarms(Equipment* equipment){ + Modbus_Point* returnHumidity = equipment -> getModbus_Point("Return Humidity"); + Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); + Modbus_Point* returnHumLowAlarmSP = equipment->getModbus_Point("Return Humidity Alarm Low SP"); + + /** + int RAHum = returnHumidity->getValue(); + int RAHumHighAlm = returnHumHighAlarmSP->getValue(); + int RAHumLowAlm = returnHumLowAlarmSP->getValue(); + + equipment->setModbus_Point("RAHum Value", RAHum); + equipment->setModbus_Point("RAHumHighAlm Value", RAHumHighAlm); + equipment->setModbus_Point("RAHumLowAlm Value", RAHumLowAlm); + */ + + if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm High Return Humidity", 1); + equipment->setModbus_Point("Alarm Low Return Humidity", 0); + } + else if (returnHumidity->getValue() < returnHumLowAlarmSP->getValue()) { + equipment->setModbus_Point("Alarm Low Return Humidity", 1); + equipment->setModbus_Point("Alarm High Return Humidity", 0); + } + else{ + equipment->setModbus_Point("Alarm High Return Humidity", 0); + equipment->setModbus_Point("Alarm Low Return Humidity", 0); + } +} + /** * @brief This function will update the Alarm status DI bits according to the Alarm Commands from Coils (Modscan) * It will also update the Common Alarm: if any alarm is active, the Common alarm will also be active. @@ -75,6 +227,12 @@ void updateAlarms(Equipment* equipment){ "Alarm Condensate Pump ON", "Alarm Fire ON", "Alarm Smoke ON" }; + const std::vector alarmAnalogs = { + "Alarm High Return Air Temp", "Alarm Low Return Air Temp", "Alarm High Return Humidity", "Alarm Low Return Humidity", + "Alarm High Supply Temp", "Alarm Low Supply Temp" + }; + + // NOTE: Per UMAS hardwire signals, alarm opened in case of normal operation, closed in case of alarm condition // 0: no alarm, 1: alarm int numAlarms = 0; @@ -86,37 +244,13 @@ void updateAlarms(Equipment* equipment){ if (alarmPoint->getValue() == 1) numAlarms++; } } + // If any of the analog alarms = 1, increment counter for number of active alarms + for (int j = 0; j* alarmAnalogPoint = equipment->getModbus_Point(alarmAnalogs[j]); + if (alarmAnalogPoint) { + if (alarmAnalogPoint->getValue() == 1) numAlarms++; + } + } if (numAlarms >= 1) equipment->setModbus_Point("Common Alarm", 1); else equipment->setModbus_Point("Common Alarm", 0); -} - -/** - * @brief The purpose of this function is for testing the RA Temp and RA Humidity alarms (Ignition HMI display) - * User will manually set Alarms through Modscan coils, which will change RA Temp or RA Humidity accordingly. - * The RA Temp alarm limits (reference Ignition UDT) are 72, 100. - * The SA Temp alarm limits (reference Ignition UDT) are 72, 78. - * The RA Humidity alarm limits (reference Ignition UDT) are 20, 60. - * If an associated alarm coil is not active, the analog values are set to a safe, un-alarmed value. - * - * NOTE: These analog alarms will not activate the Common Alarm in the Arduino test. - * Since these alarms will be set in Ignition, will not be sent over Modbus from CRAH to Ignition. - * - * This is a function used in the update() of the Running State. - * -*/ -// Note: The Common Alarm is not configured to annunciate with these analog low/high alarms. -void updateAnalogs(Equipment* equipment){ - if (equipment->getModbus_Point("RA Temp Low Alarm ON")->getValue() ==1){ - equipment->setModbus_Point("Return Air Temp", 60.0f); - } - else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Temp", 110.0f); - } - - if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 5.0f); - } - else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 80.0f); - } } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h index 23b56cb..7b80a30 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h @@ -35,16 +35,14 @@ class State; */ void updateControlMode(Equipment* equipment); -/** - * @brief Checks common alarms (non-fail alarms) and updates the Common Alarm Modbus point. - * @param equipment Pointer to the Equipment instance. - * @return true if any common alarm is active, false otherwise. - */ -void updateAlarms(Equipment* equipment); +void updateAnalogs(Equipment* equipment); +void updateReturnAirTempAlarms(Equipment* equipment); +void updateSupplyAirTempAlarms(Equipment* equipment); +void updateReturnHumidityAlarms(Equipment* equipment); /** * @brief Checks common alarms (non-fail alarms) and updates the Common Alarm Modbus point. * @param equipment Pointer to the Equipment instance. * @return true if any common alarm is active, false otherwise. */ -void updateAnalogs(Equipment* equipment); \ No newline at end of file +void updateAlarms(Equipment* equipment); \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index b9d847b..4c1198b 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -82,8 +82,11 @@ State* FailState::update(Equipment* equipment) { // Still want Control Mode and Alarms to be updated while in Fail State // Ensure BMS Command is set to Off: want operator to re-start from BMS once Leak Detect Alarm is cleared. updateControlMode(equipment); - updateAlarms(equipment); updateAnalogs(equipment); + updateReturnAirTempAlarms(equipment); + updateSupplyAirTempAlarms(equipment); + updateReturnHumidityAlarms(equipment); + updateAlarms(equipment); setPointValue(equipment, "ON/OFF Command By BMS", 0); // The only way to exit the Fail State is for Leak Detect Alarm to turn off, then enter Standby State. diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index 14a1b28..964c7fc 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -104,8 +104,11 @@ State* RunningState::update(Equipment* equipment) int BMS_Enable_Source = getPointValue(equipment, "BMS Enable Source"); // Modscan HR 2 updateControlMode(equipment); - updateAlarms(equipment); updateAnalogs(equipment); + updateReturnAirTempAlarms(equipment); + updateSupplyAirTempAlarms(equipment); + updateReturnHumidityAlarms(equipment); + updateAlarms(equipment); // Check to see if Leak Detect alarm is active (only alarm which will make unit FAIL and turn off) --> Send to FailState bool leakDetect = getPointValue(equipment, "Alarm Leak Detect"); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index 90be569..1c9492c 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -41,9 +41,9 @@ StandbyState::StandbyState() { // You can add initialization code here if needed. // These strategies are applied at the end of the update function. addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); - addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); - addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); - addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); + addStrategy("Supply Air Temp", new SingleValueStrategy(76.0f, 1.0f, 2000)); + addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 3000)); + addStrategy("Return Air Humidity", new SingleValueStrategy(25.0f, 1.0f, 4000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 300.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 300.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 300.0f, 1000)); @@ -87,8 +87,11 @@ State* StandbyState::update(Equipment* equipment) int BMS_Enable_Source = getPointValue(equipment, "BMS Enable Source"); // Modscan HR 2 updateControlMode(equipment); - updateAlarms(equipment); updateAnalogs(equipment); + updateReturnAirTempAlarms(equipment); + updateSupplyAirTempAlarms(equipment); + updateReturnHumidityAlarms(equipment); + updateAlarms(equipment); // Check to see if Leak Detect alarm is active (only alarm which will make unit FAIL and turn off) --> Send to FailState bool leakDetect = getPointValue(equipment, "Alarm Leak Detect"); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 93fc80a..647caea 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 10); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 11); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -59,27 +59,42 @@ modbusMap mb_map[] = { {COIL, 0, 0, "ON/OFF Command By BMS"}, // Receive signal from PLC - {COIL, 1, 0, "Alarm Fan 1 ON"}, // Just for Arduino testing. Sets Alarm Fan 1 to 1. - {COIL, 2, 0, "Alarm Fan 2 ON"}, // Just for Arduino testing. Sets Alarm Fan 2 to 1. - {COIL, 3, 0, "Alarm Dirty Filter ON"}, // Just for Arduino testing. Sets Alarm Dirty Filter to 1. - {COIL, 4, 0, "Alarm Leak Detect ON"}, // Just for Arduino testing. Sets Alarm Fan 1 to 1. - {COIL, 5, 0, "RA Temp Low Alarm ON"}, // Just for Arduino testing. Sets RA Temp to 68F (low alarm) - {COIL, 6, 0, "RA Temp High Alarm ON"}, // Just for Arduino testing. Sets RA Temp to 104F (high alarm) - {COIL, 7, 0, "RA Humidity Low Alarm ON"}, // Just for Arduino testing. Sets RA Humidity to 15% (low alarm) - {COIL, 8, 0, "RA Humidity High Alarm ON"}, // Just for Arduino testing. Sets RA Humidity to 65% (high alarm) - {COIL, 9, 0, "Alarm Fan 3 ON"}, // Just for Arduino testing. Sets Alarm Fan 3 to 1. - {COIL, 10, 0, "Alarm Fan 4 ON"}, // Just for Arduino testing. Sets Alarm Fan 4 to 1. - {COIL, 11, 0, "Alarm Fan 5 ON"}, // Just for Arduino testing. Sets Alarm Fan 5 to 1. - {COIL, 12, 0, "Alarm Fan 6 ON"}, // Just for Arduino testing. Sets Alarm Fan 6 to 1. - {COIL, 13, 0, "Alarm Fan 7 ON"}, // Just for Arduino testing. Sets Alarm Fan 7 to 1. - {COIL, 14, 0, "Alarm Fan 8 ON"}, // Just for Arduino testing. Sets Alarm Fan 8 to 1. - {COIL, 15, 0, "Alarm Fan 9 ON"}, // Just for Arduino testing. Sets Alarm Fan 9 to 1. - {COIL, 16, 0, "Alarm Condensate Pump ON"}, // Just for Arduino testing. Sets Alarm Condensate Pump to 1. - {COIL, 17, 0, "Alarm Fire ON"}, // Just for Arduino testing. Sets Alarm Fire to 1. - {COIL, 18, 0, "Alarm Smoke ON"}, // Just for Arduino testing. Sets Alarm Smoke to 1. + {COIL, 1, 0, "Alarm Dirty Filter ON"}, // Just for Arduino testing. Sets Alarm Dirty Filter to 1. + {COIL, 2, 0, "Alarm Leak Detect ON"}, // Just for Arduino testing. Sets Alarm Fan 1 to 1. + + {COIL, 3, 0, "Alarm Fan 1 ON"}, // Just for Arduino testing. Sets Alarm Fan 1 to 1. + {COIL, 4, 0, "Alarm Fan 2 ON"}, // Just for Arduino testing. Sets Alarm Fan 2 to 1. + {COIL, 5, 0, "Alarm Fan 3 ON"}, // Just for Arduino testing. Sets Alarm Fan 3 to 1. + {COIL, 6, 0, "Alarm Fan 4 ON"}, // Just for Arduino testing. Sets Alarm Fan 4 to 1. + {COIL, 7, 0, "Alarm Fan 5 ON"}, // Just for Arduino testing. Sets Alarm Fan 5 to 1. + {COIL, 8, 0, "Alarm Fan 6 ON"}, // Just for Arduino testing. Sets Alarm Fan 6 to 1. + {COIL, 9, 0, "Alarm Fan 7 ON"}, // Just for Arduino testing. Sets Alarm Fan 7 to 1. + {COIL, 10, 0, "Alarm Fan 8 ON"}, // Just for Arduino testing. Sets Alarm Fan 8 to 1. + {COIL, 11, 0, "Alarm Fan 9 ON"}, // Just for Arduino testing. Sets Alarm Fan 9 to 1. + {COIL, 12, 0, "Alarm Condensate Pump ON"}, // Just for Arduino testing. Sets Alarm Condensate Pump to 1. + {COIL, 13, 0, "Alarm Fire ON"}, // Just for Arduino testing. Sets Alarm Fire to 1. + {COIL, 14, 0, "Alarm Smoke ON"}, // Just for Arduino testing. Sets Alarm Smoke to 1. + + {COIL, 15, 0, "RA Temp Low Alarm ON"}, // Just for Arduino testing. Sets RA Temp to 68F (low alarm) + {COIL, 16, 0, "RA Temp NORMAL"}, // Just for Arduino testing. Sets RA Temp to 68F (low alarm) + {COIL, 17, 0, "RA Temp High Alarm ON"}, // Just for Arduino testing. Sets RA Temp to 104F (high alarm) + + {COIL, 18, 0, "SA Temp Low Alarm ON"}, // Just for Arduino testing. Sets RA Temp to 68F (low alarm) + {COIL, 19, 0, "SA Temp NORMAL"}, // Just for Arduino testing. Sets RA Temp to 68F (low alarm) + {COIL, 20, 0, "SA Temp High Alarm ON"}, // Just for Arduino testing. Sets RA Temp to 104F (high alarm) + + {COIL, 21, 0, "RA Humidity Low Alarm ON"}, // Just for Arduino testing. Sets RA Humidity to 15% (low alarm) + {COIL, 22, 0, "RA Humidity NORMAL"}, // Just for Arduino testing. Sets RA Temp to 68F (low alarm) + {COIL, 23, 0, "RA Humidity High Alarm ON"}, // Just for Arduino testing. Sets RA Humidity to 65% (high alarm) {DI, 4, 0, "Alarm Leak Detect"}, {DI, 5, 0, "Alarm Dirty Filter"}, + {DI, 6, 0, "Alarm High Return Air Temp"}, // suggested default 100, operator inputs High RA Temp SP for alarm limit + {DI, 7, 0, "Alarm Low Return Air Temp"}, // suggested default 72, operator inputs Low RA Temp SP for alarm limit + {DI, 8, 0, "Alarm High Supply Temp"}, // suggested default 78, operator inputs High SA Temp SP for alarm limit + {DI, 9, 0, "Alarm Low Supply Temp"}, // suggested default 72, operator inputs Low SA Temp SP for alarm limit + {DI, 10, 0, "Alarm High Return Humidity"}, // suggested default 60, operator inputs High Return Humidity SP for alarm limit + {DI, 11, 0, "Alarm Low Return Humidity"}, // suggested default 20, operator inputs Low Return Humidity SP for alarm limit {DI, 12, 0, "Common Alarm"}, // Send to PLC {DI, 14, 0, "Alarm Condensate Pump"}, {DI, 15, 0, "Alarm Smoke"}, @@ -137,12 +152,12 @@ modbusMap mb_map[] = {IR_FLOAT, 77, 0, "Amps Fan 8"}, {IR_FLOAT, 79, 0, "Amps Fan 9"}, - {HR_FLOAT, 1, 0, "High Return Air Temp Setpoint"}, // default: 100, set locally on unit - {HR_FLOAT, 3, 0, "Low Return Air Temp Setpoint"}, // default: 72, set locally on unit - {HR_FLOAT, 5, 0, "High Supply Air Temp Setpoint"}, // default: 78, set locally on unit - {HR_FLOAT, 7, 0, "Low Return Air Temp Setpoint"}, // default: 72, set locally on unit - {HR_FLOAT, 9, 0, "High Return Humidity Setpoint"}, // default: 60, set locally on unit - {HR_FLOAT, 11, 0, "Low Return Humidity Setpoint"}, // default: 20, set locally on unit + {HR_FLOAT, 1, 100, "Return Air Temp Alarm High SP"}, // default: 100, set locally on unit + {HR_FLOAT, 3, 72, "Return Air Temp Alarm Low SP"}, // default: 72, set locally on unit + {HR_FLOAT, 5, 78, "Supply Air Temp Alarm High SP"}, // default: 78, set locally on unit + {HR_FLOAT, 7, 72, "Supply Air Temp Alarm Low SP"}, // default: 72, set locally on unit + {HR_FLOAT, 9, 60, "Return Humidity Alarm High SP"}, // default: 60, set locally on unit + {HR_FLOAT, 11, 20, "Return Humidity Alarm Low SP"}, // default: 20, set locally on unit {HR_FLOAT, 13, 0, "Fan Speed Setpoint"}, // Receive signal from PLC {HR_FLOAT, 17, 0, "Supply Air Temp Setpoint"}, // Receive signal from PLC {HR_FLOAT, 19, 0, "Return Air Temp Setpoint"}, // set locally on unit From 9f48ade1862dd04b401b7b93765d58f09a504caf Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 21:11:23 -0600 Subject: [PATCH 35/51] removed float initialize --- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 647caea..8e0a308 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -152,12 +152,12 @@ modbusMap mb_map[] = {IR_FLOAT, 77, 0, "Amps Fan 8"}, {IR_FLOAT, 79, 0, "Amps Fan 9"}, - {HR_FLOAT, 1, 100, "Return Air Temp Alarm High SP"}, // default: 100, set locally on unit - {HR_FLOAT, 3, 72, "Return Air Temp Alarm Low SP"}, // default: 72, set locally on unit - {HR_FLOAT, 5, 78, "Supply Air Temp Alarm High SP"}, // default: 78, set locally on unit - {HR_FLOAT, 7, 72, "Supply Air Temp Alarm Low SP"}, // default: 72, set locally on unit - {HR_FLOAT, 9, 60, "Return Humidity Alarm High SP"}, // default: 60, set locally on unit - {HR_FLOAT, 11, 20, "Return Humidity Alarm Low SP"}, // default: 20, set locally on unit + {HR_FLOAT, 1, 0, "Return Air Temp Alarm High SP"}, // default: 100, set locally on unit + {HR_FLOAT, 3, 0, "Return Air Temp Alarm Low SP"}, // default: 72, set locally on unit + {HR_FLOAT, 5, 0, "Supply Air Temp Alarm High SP"}, // default: 78, set locally on unit + {HR_FLOAT, 7, 0, "Supply Air Temp Alarm Low SP"}, // default: 72, set locally on unit + {HR_FLOAT, 9, 0, "Return Humidity Alarm High SP"}, // default: 60, set locally on unit + {HR_FLOAT, 11, 0, "Return Humidity Alarm Low SP"}, // default: 20, set locally on unit {HR_FLOAT, 13, 0, "Fan Speed Setpoint"}, // Receive signal from PLC {HR_FLOAT, 17, 0, "Supply Air Temp Setpoint"}, // Receive signal from PLC {HR_FLOAT, 19, 0, "Return Air Temp Setpoint"}, // set locally on unit From acf981f5907c7583240f9ffdc10f231cfb1f9b11 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Mon, 8 Dec 2025 21:14:25 -0600 Subject: [PATCH 36/51] asf --- src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index 930247a..03a9910 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -83,6 +83,7 @@ void updateReturnAirTempAlarms(Equipment* equipment){ //Modbus_Point* returnTempHighAlarm = equipment->getModbus_Point("Alarm High Return Air Temp"); //Modbus_Point* returnTempLowAlarm = equipment->getModbus_Point("Alarm Low Return Air Temp"); + /** int RATemp = returnAirTemp->getValue(); int RATempHighAlm = returnTempHighAlarmSP->getValue(); int RATempLowAlm = returnTempLowAlarmSP->getValue(); @@ -90,6 +91,7 @@ void updateReturnAirTempAlarms(Equipment* equipment){ equipment->setModbus_Point("RATemp Value", RATemp); equipment->setModbus_Point("RATempHighAlm Value", RATempHighAlm); equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); + */ if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { equipment->setModbus_Point("Alarm Low Return Air Temp", 1); @@ -115,6 +117,7 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); Modbus_Point* supplyTempLowAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm Low SP"); + /** int SATemp = supplyAirTemp->getValue(); int SATempHighAlm = supplyTempHighAlarmSP->getValue(); int SATempLowAlm = supplyTempLowAlarmSP->getValue(); @@ -122,7 +125,7 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ equipment->setModbus_Point("SATemp Value", SATemp); equipment->setModbus_Point("SATempHighAlm Value", SATempHighAlm); equipment->setModbus_Point("SATempLowAlm Value", SATempLowAlm); - + */ if (supplyAirTemp->getValue() > supplyTempHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Supply Temp", 1); @@ -143,6 +146,7 @@ void updateReturnHumidityAlarms(Equipment* equipment){ Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); Modbus_Point* returnHumLowAlarmSP = equipment->getModbus_Point("Return Humidity Alarm Low SP"); + /** int RAHum = returnHumidity->getValue(); int RAHumHighAlm = returnHumHighAlarmSP->getValue(); int RAHumLowAlm = returnHumLowAlarmSP->getValue(); @@ -150,6 +154,7 @@ void updateReturnHumidityAlarms(Equipment* equipment){ equipment->setModbus_Point("RAHum Value", RAHum); equipment->setModbus_Point("RAHumHighAlm Value", RAHumHighAlm); equipment->setModbus_Point("RAHumLowAlm Value", RAHumLowAlm); + */ if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Humidity", 1); From c49c99869de9c0d63ac2da22fa7657fff8441019 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 9 Dec 2025 08:03:23 -0600 Subject: [PATCH 37/51] updates from EG CRAH --- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 60 +++----------------- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h | 1 - src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp | 2 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp | 6 +- src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp | 2 +- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 2 +- 6 files changed, 14 insertions(+), 59 deletions(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index 0d661c2..9651fa2 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -53,46 +53,34 @@ void updateControlMode(Equipment* equipment){ equipment->setModbus_Point("Control Mode Selected", Control_Mode_Selected); } -/** - * @brief The purpose of this function is for testing the RA Temp, SA Temp, and RA Humidity alarms (Ignition HMI display) - * User will manually set Alarms through Modscan coils, which will change RA Temp or RA Humidity accordingly. - * The RA Temp alarm limits (reference Ignition UDT) are 72, 100. - * The SA Temp alarm limits (reference Ignition UDT) are 72, 78. - * The RA Humidity alarm limits (reference Ignition UDT) are 20, 60. - * If an associated alarm coil is not active, the analog values are set to a safe, un-alarmed value. - * - * This is a function used in the update() of the Running State. - * -*/ - void updateAnalogs(Equipment* equipment){ if (equipment->getModbus_Point("RA Temp NORMAL")->getValue()==1){ - equipment->setModbus_Point("Return Air Temp", 86.0f); + equipment->setModbus_Point("Return Air Temp", 84.0f); equipment->setModbus_Point("RA Temp Low Alarm ON", 0); equipment->setModbus_Point("RA Temp High Alarm ON", 0); equipment->setModbus_Point("RA Temp NORMAL", 0); } else if (equipment->getModbus_Point("RA Temp Low Alarm ON")->getValue() ==1){ - equipment->setModbus_Point("Return Air Temp", 62.0f); + equipment->setModbus_Point("Return Air Temp", 60.0f); equipment->setModbus_Point("RA Temp High Alarm ON", 0); } else if (equipment->getModbus_Point("RA Temp High Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Temp", 106.0f); + equipment->setModbus_Point("Return Air Temp", 110.0f); equipment->setModbus_Point("RA Temp Low Alarm ON", 0); } if (equipment->getModbus_Point("RA Humidity NORMAL")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 25.0f); + equipment->setModbus_Point("Return Humidity", 25.0f); equipment->setModbus_Point("RA Humidity Low Alarm ON", 0); equipment->setModbus_Point("RA Humidity High Alarm ON", 0); equipment->setModbus_Point("RA Humidity NORMAL", 0); } else if (equipment->getModbus_Point("RA Humidity Low Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 6.0f); + equipment->setModbus_Point("Return Humidity", 5.0f); equipment->setModbus_Point("RA Humidity High Alarm ON", 0); } else if (equipment->getModbus_Point("RA Humidity High Alarm ON")->getValue()==1){ - equipment->setModbus_Point("Return Air Humidity", 80.0f); + equipment->setModbus_Point("Return Humidity", 80.0f); equipment->setModbus_Point("RA Humidity Low Alarm ON", 0); } @@ -117,32 +105,18 @@ void updateReturnAirTempAlarms(Equipment* equipment){ Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); Modbus_Point* returnTempLowAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm Low SP"); - //Modbus_Point* returnTempHighAlarm = equipment->getModbus_Point("Alarm High Return Air Temp"); - //Modbus_Point* returnTempLowAlarm = equipment->getModbus_Point("Alarm Low Return Air Temp"); - - //int RATemp = returnAirTemp->getValue(); - //int RATempHighAlm = returnTempHighAlarmSP->getValue(); - //int RATempLowAlm = returnTempLowAlarmSP->getValue(); - - //equipment->setModbus_Point("RATemp Value", RATemp); - //equipment->setModbus_Point("RATempHighAlm Value", RATempHighAlm); - //equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { equipment->setModbus_Point("Alarm Low Return Air Temp", 1); equipment->setModbus_Point("Alarm High Return Air Temp", 0); - //returnTempHighAlarm->setValue(1); } else if (returnAirTemp->getValue() > returnTempHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Air Temp", 1); equipment->setModbus_Point("Alarm Low Return Air Temp", 0); - //returnTempLowAlarm->setValue(1); } else{ equipment->setModbus_Point("Alarm High Return Air Temp", 0); equipment->setModbus_Point("Alarm Low Return Air Temp", 0); - //returnTempHighAlarm->setValue(0); - //returnTempLowAlarm->setValue(0); } } @@ -152,16 +126,6 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); Modbus_Point* supplyTempLowAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm Low SP"); - /** - int SATemp = supplyAirTemp->getValue(); - int SATempHighAlm = supplyTempHighAlarmSP->getValue(); - int SATempLowAlm = supplyTempLowAlarmSP->getValue(); - - equipment->setModbus_Point("SATemp Value", SATemp); - equipment->setModbus_Point("SATempHighAlm Value", SATempHighAlm); - equipment->setModbus_Point("SATempLowAlm Value", SATempLowAlm); - */ - if (supplyAirTemp->getValue() > supplyTempHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Supply Temp", 1); equipment->setModbus_Point("Alarm Low Supply Temp", 0); @@ -181,16 +145,6 @@ void updateReturnHumidityAlarms(Equipment* equipment){ Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); Modbus_Point* returnHumLowAlarmSP = equipment->getModbus_Point("Return Humidity Alarm Low SP"); - /** - int RAHum = returnHumidity->getValue(); - int RAHumHighAlm = returnHumHighAlarmSP->getValue(); - int RAHumLowAlm = returnHumLowAlarmSP->getValue(); - - equipment->setModbus_Point("RAHum Value", RAHum); - equipment->setModbus_Point("RAHumHighAlm Value", RAHumHighAlm); - equipment->setModbus_Point("RAHumLowAlm Value", RAHumLowAlm); - */ - if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Humidity", 1); equipment->setModbus_Point("Alarm Low Return Humidity", 0); @@ -251,6 +205,8 @@ void updateAlarms(Equipment* equipment){ if (alarmAnalogPoint->getValue() == 1) numAlarms++; } } + // If any alarms are active, set the Common Alarm = 1, else Common Alarm = 0. + if (numAlarms >= 1) equipment->setModbus_Point("Common Alarm", 1); else equipment->setModbus_Point("Common Alarm", 0); } \ No newline at end of file diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h index 7b80a30..7c49f8f 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.h @@ -34,7 +34,6 @@ class State; * @return The selected control mode (int). */ void updateControlMode(Equipment* equipment); - void updateAnalogs(Equipment* equipment); void updateReturnAirTempAlarms(Equipment* equipment); void updateSupplyAirTempAlarms(Equipment* equipment); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp index 4c1198b..5e9c124 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Fail.cpp @@ -42,7 +42,7 @@ FailState::FailState(const std::vector& activeAlarms) { addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); addStrategy("Supply Air Temp", new SingleValueStrategy(74.0f, 1.0f, 1000)); addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 1000)); - addStrategy("Return Air Humidity", new SingleValueStrategy(35.0f, 2.0f, 1000)); + addStrategy("Return Humidity", new SingleValueStrategy(30.0f, 1.0f, 3000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 300.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 300.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 300.0f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp index 964c7fc..9290275 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Running.cpp @@ -71,9 +71,9 @@ RunningState::RunningState() { addStrategy("Operating Hours Fan 7", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 8", new TotalizerStrategy(1000)); addStrategy("Operating Hours Fan 9", new TotalizerStrategy(1000)); - addStrategy("Supply Air Temp", new SawStrategy(60.0f, 100.0f, 2.2f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan - addStrategy("Return Air Humidity", new SawStrategy(25.0f, 40.0f, 1.1f, 1000)); - addStrategy("Return Air Temp", new SawStrategy(84.0f, 87.0f, 0.2f, 1000)); + addStrategy("Supply Air Temp", new SawStrategy(73.0f, 77.0f, 0.2f, 1000)); // Won't initialize at lower bound; always initializes at 0 b/c FLOAT; initialize manually via Modscan + addStrategy("Return Humidity", new SawStrategy(25.0f, 35.0f, 0.2f, 1000)); + addStrategy("Return Air Temp", new SawStrategy(80.0f, 90.0f, 0.2f, 1000)); addStrategy("Filter Differential Pressure", new SawStrategy(0.1f, 5.1f, 0.2f, 1000)); addStrategy("CW Valve Position", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); // SAT must be greater than SAT Setpoint for this PID to work. addStrategy("CRAH Heartbeat", new SawStrategy(0.0f, 60.0f, 1.0f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp index 1c9492c..c863fcd 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/State_Standby.cpp @@ -43,7 +43,7 @@ StandbyState::StandbyState() { addStrategy("CW Valve Position", new RampStrategy(0.0f, 5.0f, 1000)); addStrategy("Supply Air Temp", new SingleValueStrategy(76.0f, 1.0f, 2000)); addStrategy("Return Air Temp", new SingleValueStrategy(86.0f, 1.0f, 3000)); - addStrategy("Return Air Humidity", new SingleValueStrategy(25.0f, 1.0f, 4000)); + addStrategy("Return Humidity", new SingleValueStrategy(25.0f, 1.0f, 4000)); addStrategy("Speed Fan 1", new RampStrategy(0.0f, 300.0f, 1000)); addStrategy("Speed Fan 2", new RampStrategy(0.0f, 300.0f, 1000)); addStrategy("Speed Fan 3", new RampStrategy(0.0f, 300.0f, 1000)); diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 8e0a308..614956b 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -101,7 +101,7 @@ modbusMap mb_map[] = {DI, 16, 0, "Alarm Fire"}, {IR_FLOAT, 1, 0, "Supply Air Temp"}, - {IR_FLOAT, 3, 0, "Return Air Humidity"}, // Ignition visual only + {IR_FLOAT, 3, 0, "Return Humidity"}, // Ignition visual only {IR_FLOAT, 5, 0, "Return Air Temp"}, // Send to PLC {IR_FLOAT, 7, 0, "Filter Differential Pressure"}, // sawStrategy between 0 and 5 {IR_FLOAT, 9, 0, "CW Valve Position"}, From adb319d7633361b39e3726b58093d4da751f7fc5 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 9 Dec 2025 16:36:33 -0600 Subject: [PATCH 38/51] IP address changes for Schertz setup --- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 614956b..6ef768a 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 11); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 49); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ @@ -56,6 +56,9 @@ * 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. */ + + // "One-Based" Addressing for IR, HR registers + modbusMap mb_map[] = { {COIL, 0, 0, "ON/OFF Command By BMS"}, // Receive signal from PLC From 6630a016381e3b531772a68614af5a48fd7193f7 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 9 Dec 2025 19:20:58 -0600 Subject: [PATCH 39/51] update IP for local setup --- src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index 230f994..7bf2f7f 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 11); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 63); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ From d30cba503642a67c6b735e504323737f742f1895 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Wed, 10 Dec 2025 09:37:18 -0600 Subject: [PATCH 40/51] updated IPs for loading Schertz arduinos --- .../StateUtils.cpp | 38 ------------------- .../State_Running.cpp | 4 -- .../State_Standby.cpp | 7 ---- .../PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h | 2 +- 4 files changed, 1 insertion(+), 50 deletions(-) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index 03a9910..339d5c8 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -73,43 +73,25 @@ void updateAnalogs(Equipment* equipment){ equipment->setModbus_Point("Supply Air Temp", 90.0f); equipment->setModbus_Point("SA Temp Low Alarm ON", 0); } - } void updateReturnAirTempAlarms(Equipment* equipment){ Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); Modbus_Point* returnTempLowAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm Low SP"); - //Modbus_Point* returnTempHighAlarm = equipment->getModbus_Point("Alarm High Return Air Temp"); - //Modbus_Point* returnTempLowAlarm = equipment->getModbus_Point("Alarm Low Return Air Temp"); - - /** - int RATemp = returnAirTemp->getValue(); - int RATempHighAlm = returnTempHighAlarmSP->getValue(); - int RATempLowAlm = returnTempLowAlarmSP->getValue(); - - equipment->setModbus_Point("RATemp Value", RATemp); - equipment->setModbus_Point("RATempHighAlm Value", RATempHighAlm); - equipment->setModbus_Point("RATempLowAlm Value", RATempLowAlm); - */ if (returnAirTemp->getValue() < returnTempLowAlarmSP->getValue()) { equipment->setModbus_Point("Alarm Low Return Air Temp", 1); equipment->setModbus_Point("Alarm High Return Air Temp", 0); - //returnTempHighAlarm->setValue(1); } else if (returnAirTemp->getValue() > returnTempHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Air Temp", 1); equipment->setModbus_Point("Alarm Low Return Air Temp", 0); - //returnTempLowAlarm->setValue(1); } else{ equipment->setModbus_Point("Alarm High Return Air Temp", 0); equipment->setModbus_Point("Alarm Low Return Air Temp", 0); - //returnTempHighAlarm->setValue(0); - //returnTempLowAlarm->setValue(0); } - } void updateSupplyAirTempAlarms(Equipment* equipment){ @@ -117,16 +99,6 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); Modbus_Point* supplyTempLowAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm Low SP"); - /** - int SATemp = supplyAirTemp->getValue(); - int SATempHighAlm = supplyTempHighAlarmSP->getValue(); - int SATempLowAlm = supplyTempLowAlarmSP->getValue(); - - equipment->setModbus_Point("SATemp Value", SATemp); - equipment->setModbus_Point("SATempHighAlm Value", SATempHighAlm); - equipment->setModbus_Point("SATempLowAlm Value", SATempLowAlm); - */ - if (supplyAirTemp->getValue() > supplyTempHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Supply Temp", 1); equipment->setModbus_Point("Alarm Low Supply Temp", 0); @@ -146,16 +118,6 @@ void updateReturnHumidityAlarms(Equipment* equipment){ Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); Modbus_Point* returnHumLowAlarmSP = equipment->getModbus_Point("Return Humidity Alarm Low SP"); - /** - int RAHum = returnHumidity->getValue(); - int RAHumHighAlm = returnHumHighAlarmSP->getValue(); - int RAHumLowAlm = returnHumLowAlarmSP->getValue(); - - equipment->setModbus_Point("RAHum Value", RAHum); - equipment->setModbus_Point("RAHumHighAlm Value", RAHumHighAlm); - equipment->setModbus_Point("RAHumLowAlm Value", RAHumLowAlm); - */ - if (returnHumidity->getValue() > returnHumHighAlarmSP->getValue()) { equipment->setModbus_Point("Alarm High Return Humidity", 1); equipment->setModbus_Point("Alarm Low Return Humidity", 0); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp index b7a5117..bca9ab6 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Running.cpp @@ -48,10 +48,6 @@ RunningState::RunningState() { addStrategy("Return Air Temp", new SawStrategy(78.0f, 88.0f, 1.0f, 3000)); addStrategy("Supply Air Temp", new SawStrategy(73.0f, 77.0f, 1.0f, 5000)); - //addStrategy("Return Humidity", new SingleValueStrategy(10.0f, 0.0f, 1000)); - //addStrategy("Return Air Temp", new SingleValueStrategy(50.0f, 0.0f, 1000)); - //addStrategy("Supply Air Temp", new SingleValueStrategy(60.0f, 0.0f, 1000)); - addStrategy("Supply Air Flow", new SawStrategy(7.0f, 10.0f, 1.0f, 1000)); addStrategy("Fan Speed", new PIDStrategy("Return Air Temp Setpoint", 1000, "Return Air Temp")); addStrategy("Fluid Control Valve Position 1", new PIDStrategy("Supply Air Temp Setpoint", 1000, "Supply Air Temp")); diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp index 982a353..cd0f010 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/State_Standby.cpp @@ -46,13 +46,6 @@ StandbyState::StandbyState() { addStrategy("Supply Air Flow", new RampStrategy(0.0f, 1.0f, 5000)); addStrategy("Fluid Control Valve Position 1", new RampStrategy(0.0f, 5.0f, 1000)); addStrategy("Fluid Control Valve Position 2", new RampStrategy(0.0f, 5.0f, 1000)); - - //addStrategy("Return Humidity Alarm High SP", new SingleValueStrategy(60.0f, 0.0f, 1000)); - //addStrategy("Return Humidity Alarm Low SP", new SingleValueStrategy(20.0f, 0.0f, 1000)); - //addStrategy("Return Air Temp Alarm High SP", new SingleValueStrategy(100.0f, 0.0f, 1000)); - //addStrategy("Return Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 0.0f, 1000)); - //addStrategy("Supply Air Temp Alarm High SP", new SingleValueStrategy(78.0f, 0.0f, 1000)); - //addStrategy("Supply Air Temp Alarm Low SP", new SingleValueStrategy(72.0f, 0.0f, 1000)); } /** diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h index 7bf2f7f..695c5ac 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 63); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 66); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ From 72feb876038ab5a08846897b60e0cfdb6096d307 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Wed, 10 Dec 2025 16:34:29 -0600 Subject: [PATCH 41/51] local testing adjustments --- platformio.ini | 2 +- .../CHILLER/CH_York_YVAA_RTU/State_Fail.cpp | 42 ++++++++--------- .../CH_York_YVAA_RTU/State_Running.cpp | 46 +++++++++---------- .../CH_York_YVAA_RTU/State_Standby.cpp | 41 ++++++++--------- src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 12 ++--- 5 files changed, 71 insertions(+), 72 deletions(-) diff --git a/platformio.ini b/platformio.ini index 144a2c8..32af992 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,7 +14,7 @@ default_envs = CH_York_YVAA_RTU ; Select here the name of the configuration you want to download [env] -upload_port = COM9 +upload_port = COM11 [common_env_options] framework = arduino diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp index d3996c3..0ea3225 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Fail.cpp @@ -37,28 +37,28 @@ */ template<> FailState::FailState(const std::vector& activeFaults) { - addStrategy("Supply Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Return Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 1000)); + addStrategy("Supply Temp", new SingleValueStrategy(80.0f, 1.0f, 10000)); + addStrategy("Return Temp", new SingleValueStrategy(80.0f, 1.0f, 10000)); + addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 10000)); - addStrategy("System CHW Out", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("System CHW In", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 1000)); - addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 1000)); - addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 1000)); - addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 1000)); - addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 1000)); - addStrategy("VSD Output Frequency", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 1 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 2 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); + addStrategy("System CHW Out", new SingleValueStrategy(80.0f, 1.0f, 10000)); + addStrategy("System CHW In", new SingleValueStrategy(80.0f, 1.0f, 10000)); + addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 10000)); + addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 10000)); + addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 10000)); + addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 10000)); + addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 10000)); + addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 10000)); + addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 10000)); + addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 10000)); + addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 10000)); + addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 10000)); + addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 10000)); + addStrategy("VSD Output Frequency", new SingleValueStrategy(0.0f, 0.0f, 10000)); + addStrategy("Sys 1 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 10000)); + addStrategy("Sys 2 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 10000)); + addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 10000)); + addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 10000)); } /** diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp index b476d17..6c3bb3c 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Running.cpp @@ -41,30 +41,30 @@ */ template<> RunningState::RunningState() { - addStrategy("Supply Temp", new RampStrategy(67.0f, 1.0f, 1000)); - addStrategy("Return Temp", new SawStrategy(79.0f, 83.0f, 1.0f, 1000)); - addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 1000)); + addStrategy("Supply Temp", new RampStrategy(67.0f, 1.0f, 3000)); + addStrategy("Return Temp", new SawStrategy(79.0f, 83.0f, 1.0f, 4000)); + addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 5000)); - addStrategy("System CHW Out", new RampStrategy(67.0f, 1.0f, 1000)); - addStrategy("System CHW In", new RampStrategy(81.0f, 1.0f, 1000)); - addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(125.0f, 5.0f, 1000)); - addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(125.0f, 5.0f, 1000)); - addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(450.0f, 5.0f, 1000)); - addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(450.0f, 5.0f, 1000)); - addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 2.0f, 1000)); - addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 2.0f, 1000)); - addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(375.0f, 4.0f, 1000)); - addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(375.0f, 4.0f, 1000)); - addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(93.0f, 2.0f, 1000)); - addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(93.0f, 2.0f, 1000)); - addStrategy("Sys 1 Run Hours", new TotalizerStrategy(1000)); - addStrategy("Sys 2 Run Hours", new TotalizerStrategy(1000)); - addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 1000)); - addStrategy("VSD Output Frequency", new SingleValueStrategy(59.0f, 1.0f, 1000)); - addStrategy("Sys 1 Fan KW", new SingleValueStrategy(35.0f, 2.0f, 1000)); - addStrategy("Sys 2 Fan KW", new SingleValueStrategy(23.0f, 2.0f, 1000)); - addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(304.0f, 5.0f, 1000)); - addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(198.0f, 5.0f, 1000)); + addStrategy("System CHW Out", new RampStrategy(67.0f, 1.0f, 3000)); + addStrategy("System CHW In", new RampStrategy(81.0f, 1.0f, 4000)); + addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(125.0f, 5.0f, 5000)); + addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(125.0f, 5.0f, 5000)); + addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(450.0f, 5.0f, 5000)); + addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(450.0f, 5.0f, 5000)); + addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 2.0f, 5000)); + addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 2.0f, 5000)); + addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(375.0f, 4.0f, 5000)); + addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(375.0f, 4.0f, 5000)); + addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(93.0f, 2.0f, 5000)); + addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(93.0f, 2.0f, 5000)); + addStrategy("Sys 1 Run Hours", new TotalizerStrategy(5000)); + addStrategy("Sys 2 Run Hours", new TotalizerStrategy(5000)); + addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 10000)); + addStrategy("VSD Output Frequency", new SingleValueStrategy(59.0f, 1.0f, 10000)); + addStrategy("Sys 1 Fan KW", new SingleValueStrategy(35.0f, 2.0f, 10000)); + addStrategy("Sys 2 Fan KW", new SingleValueStrategy(23.0f, 2.0f, 10000)); + addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(304.0f, 5.0f, 10000)); + addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(198.0f, 5.0f, 10000)); } /** diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp index b5309ba..c4ebf04 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/State_Standby.cpp @@ -38,28 +38,27 @@ */ template<> StandbyState::StandbyState() { - addStrategy("Supply Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Return Temp", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 1000)); + addStrategy("Supply Temp", new SingleValueStrategy(80.0f, 1.0f, 3000)); + addStrategy("Return Temp", new SingleValueStrategy(80.0f, 1.0f, 3000)); + addStrategy("Ambient Temp", new SingleValueStrategy(100.0f, 1.0f, 4000)); - addStrategy("System CHW Out", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("System CHW In", new SingleValueStrategy(80.0f, 1.0f, 1000)); - addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 1000)); - addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 1000)); - addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 1000)); - addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 1000)); - addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 1000)); - addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Local Leaving Temp Setpoint", new SingleValueStrategy(70.0f, 0.0f, 1000)); - addStrategy("VSD Output Frequency", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 1 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 2 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); - addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 1000)); + addStrategy("System CHW Out", new SingleValueStrategy(80.0f, 1.0f, 3000)); + addStrategy("System CHW In", new SingleValueStrategy(80.0f, 1.0f, 3000)); + addStrategy("Sys 1 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 5000)); + addStrategy("Sys 2 Condenser Temp", new SingleValueStrategy(124.0f, 1.0f, 5000)); + addStrategy("Sys 1 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 5000)); + addStrategy("Sys 2 Oil Pressure", new SingleValueStrategy(420.0f, 1.0f, 5000)); + addStrategy("Sys 1 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 5000)); + addStrategy("Sys 2 Suction Pressure", new SingleValueStrategy(70.0f, 1.0f, 5000)); + addStrategy("Sys 1 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 5000)); + addStrategy("Sys 2 Discharge Pressure", new SingleValueStrategy(70.0f, 1.0f, 5000)); + addStrategy("Sys 1 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 5000)); + addStrategy("Sys 2 Compressor Pct FLA", new SingleValueStrategy(0.0f, 0.0f, 5000)); + addStrategy("VSD Output Frequency", new SingleValueStrategy(0.0f, 0.0f, 5000)); + addStrategy("Sys 1 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 5000)); + addStrategy("Sys 2 Fan KW", new SingleValueStrategy(0.0f, 0.0f, 5000)); + addStrategy("Sys 1 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 5000)); + addStrategy("Sys 2 Compressor KW", new SingleValueStrategy(0.0f, 0.0f, 5000)); } diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index 79e7383..b83e30d 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -54,10 +54,10 @@ */ modbusMap mb_map[] = { - {COIL, 0, 0, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. + {COIL, 0, 1, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) - {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) + {COIL, 3, 1, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) {COIL, 4, 0, "Sys 2 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) {COIL, 5, 0, "Free Cooling Mode ON"}, // Use in Modscan - Used for Arduino simulation only @@ -69,12 +69,12 @@ modbusMap mb_map[] = {IR, 165, 0, "Free Cooling Valve"}, {HR, 0, 0, "Chiller Status"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {HR, 1, 0, "Chiller Temp Setpoint"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only + {HR, 1, 60, "Chiller Temp Setpoint"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only {HR, 2, 0, "Supply Temp"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only {HR, 3, 0, "Return Temp"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only - {HR, 4, 70, "System CHW Out"}, - {HR, 5, 70, "System CHW In"}, + {HR_10x, 4, 700, "System CHW Out"}, + {HR_10x, 5, 700, "System CHW In"}, {HR_10x, 7, 0, "Sys 1 Condenser Temp"}, {HR_10x, 9, 0, "Ambient Temp"}, @@ -99,7 +99,7 @@ modbusMap mb_map[] = {HR, 31, 77, "Sys 2 Operational Code"}, // 77:not running, 78:running, 82:free cooling {HR, 32, 0, "Sys 2 Fault Code"}, // 56:condenser fan VSD warning - {HR, 39, 0, "Local Leaving Temp Setpoint"}, + {HR_10x, 39, 710, "Local Leaving Temp Setpoint"}, // just an assumption {HR_10x, 49, 0, "Sys 2 Condenser Temp"}, {HR_10x, 140, 0, "Sys 1 Fan KW"}, From 79e28c1f340a22b2063120fe819a3ceb7daa5bbb Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Wed, 10 Dec 2025 18:24:39 -0600 Subject: [PATCH 42/51] local tests --- src/BMS/CHILLER/CH_York_YVAA_RTU/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h index b83e30d..dcf5f0b 100644 --- a/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h +++ b/src/BMS/CHILLER/CH_York_YVAA_RTU/config.h @@ -57,7 +57,7 @@ modbusMap mb_map[] = {COIL, 0, 1, "Chiller Start Command"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only. Signal should come from PLC. {COIL, 1, 0, "Sys 1 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) {COIL, 2, 0, "Sys 2 Alarm"}, // Use in Modscan - Hard IO in SCP, Used for Arduino simulation only --> INDICATION ONLY (assumption) - {COIL, 3, 1, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) + {COIL, 3, 0, "Sys 1 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) {COIL, 4, 0, "Sys 2 Fan Fault ON"}, // Use in Modscan - Used for Arduino simulation only --> FAILSTATE (assumption) {COIL, 5, 0, "Free Cooling Mode ON"}, // Use in Modscan - Used for Arduino simulation only From 08436c1df6fe21867f1f2d7d1ccfb7c2567f3cdd Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 12 Dec 2025 11:26:39 -0700 Subject: [PATCH 43/51] added comments --- .../CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp index 339d5c8..7afd68b 100644 --- a/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/PHX3_CRAH_LIEBERT_80_SLAB_TCP/StateUtils.cpp @@ -28,6 +28,12 @@ #include #endif +/** The purpose of this function is to change the RA Temp, SA Temp, RA Humidity values for the purpose of testing alarms in Ignition. + * There are LOW and HIGH coils, which when activated will set the analog to a low/high range. + * The NORMAL coil will send a one-shot to set the associated analog value back into a normal range. + * If in a RunningState, the analog value will follow it's normal function (typically a sawStrategy). + */ + void updateAnalogs(Equipment* equipment){ if (equipment->getModbus_Point("RA Temp NORMAL")->getValue()==1){ equipment->setModbus_Point("Return Air Temp", 84.0f); @@ -75,6 +81,7 @@ void updateAnalogs(Equipment* equipment){ } } +//This function updates the Alarm bit for the Return Air Temp void updateReturnAirTempAlarms(Equipment* equipment){ Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); @@ -94,6 +101,7 @@ void updateReturnAirTempAlarms(Equipment* equipment){ } } +// This function updates the Alarm bit for the Supply Air Temp void updateSupplyAirTempAlarms(Equipment* equipment){ Modbus_Point* supplyAirTemp = equipment -> getModbus_Point("Supply Air Temp"); Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); @@ -113,6 +121,7 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ } } +//This function updates the Alarm bit for the Return Humidity void updateReturnHumidityAlarms(Equipment* equipment){ Modbus_Point* returnHumidity = equipment -> getModbus_Point("Return Humidity"); Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); From cde17f28e788b2e18b88c006432f1409b9350917 Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Fri, 12 Dec 2025 11:32:17 -0700 Subject: [PATCH 44/51] added comments --- src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp index 9651fa2..f479c57 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/StateUtils.cpp @@ -53,6 +53,11 @@ void updateControlMode(Equipment* equipment){ equipment->setModbus_Point("Control Mode Selected", Control_Mode_Selected); } +/** This function will set RA Temp, SA Temp, RA Humidity analog values to a LOW or HIGH range for testing alarms in Ignition. + * There is an associated COIL for performing each of those functions. + * There is also a NORMAL bit, which sends a one-shot to reset the associated analog value back into a normal range. + */ + void updateAnalogs(Equipment* equipment){ if (equipment->getModbus_Point("RA Temp NORMAL")->getValue()==1){ equipment->setModbus_Point("Return Air Temp", 84.0f); @@ -101,6 +106,7 @@ void updateAnalogs(Equipment* equipment){ } +// Updates the RA Temp Alarms void updateReturnAirTempAlarms(Equipment* equipment){ Modbus_Point* returnAirTemp = equipment -> getModbus_Point("Return Air Temp"); Modbus_Point* returnTempHighAlarmSP = equipment->getModbus_Point("Return Air Temp Alarm High SP"); @@ -121,6 +127,7 @@ void updateReturnAirTempAlarms(Equipment* equipment){ } +// Updates the SA Temp Alarms void updateSupplyAirTempAlarms(Equipment* equipment){ Modbus_Point* supplyAirTemp = equipment -> getModbus_Point("Supply Air Temp"); Modbus_Point* supplyTempHighAlarmSP = equipment->getModbus_Point("Supply Air Temp Alarm High SP"); @@ -140,6 +147,7 @@ void updateSupplyAirTempAlarms(Equipment* equipment){ } } +// Updates the RA Humidity Alarms void updateReturnHumidityAlarms(Equipment* equipment){ Modbus_Point* returnHumidity = equipment -> getModbus_Point("Return Humidity"); Modbus_Point* returnHumHighAlarmSP = equipment->getModbus_Point("Return Humidity Alarm High SP"); From 48f0e4837a004b2c666c98e0d7888bbf841bffae Mon Sep 17 00:00:00 2001 From: DohnJev18 Date: Mon, 5 Jan 2026 15:20:52 -0600 Subject: [PATCH 45/51] Created new TCP_CRAH program names HTS_PLC Created new TCP_CRAH program names HTS_PLC --- platformio.ini | 7 + src/BMS/CRAH/CRAH_HTS_PLC_TCP/README.md | 33 +++++ src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Fail.cpp | 81 +++++++++++ .../CRAH/CRAH_HTS_PLC_TCP/State_Running.cpp | 89 ++++++++++++ .../CRAH/CRAH_HTS_PLC_TCP/State_Standby.cpp | 85 +++++++++++ src/BMS/CRAH/CRAH_HTS_PLC_TCP/config.h | 134 ++++++++++++++++++ src/BMS/CRAH/CRAH_HTS_PLC_TCP/main.cpp | 86 +++++++++++ 7 files changed, 515 insertions(+) create mode 100644 src/BMS/CRAH/CRAH_HTS_PLC_TCP/README.md create mode 100644 src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Fail.cpp create mode 100644 src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Running.cpp create mode 100644 src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Standby.cpp create mode 100644 src/BMS/CRAH/CRAH_HTS_PLC_TCP/config.h create mode 100644 src/BMS/CRAH/CRAH_HTS_PLC_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index bf5c678..e0efd5c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -35,6 +35,13 @@ extends = common_env_options build_flags = -D USE_MODBUS_IP ;Importat configuration, this flags is used to configure the program build_src_filter = -<*> + ;Add the specific folder path here ;---------------------------------------------------------------------------------------------------- +[env:CRAH_HTS_PLC_TCP] +platform = espressif32 +board = dfrobot_firebeetle2_esp32e +extends = common_env_options +build_flags = -D USE_MODBUS_IP +build_src_filter = -<*> + + [env:CRAH_PETRA_PAHHC_600_C6_TCP] platform = espressif32 board = dfrobot_firebeetle2_esp32e diff --git a/src/BMS/CRAH/CRAH_HTS_PLC_TCP/README.md b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/README.md new file mode 100644 index 0000000..355156f --- /dev/null +++ b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/README.md @@ -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 diff --git a/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Fail.cpp b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Fail.cpp new file mode 100644 index 0000000..8bc0385 --- /dev/null +++ b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Fail.cpp @@ -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 +#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/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Running.cpp b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Running.cpp new file mode 100644 index 0000000..b9e4a99 --- /dev/null +++ b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Running.cpp @@ -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 +#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/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Standby.cpp b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Standby.cpp new file mode 100644 index 0000000..20029d1 --- /dev/null +++ b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/State_Standby.cpp @@ -0,0 +1,85 @@ +/** + * @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/BMS/CRAH/CRAH_HTS_PLC_TCP/config.h b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/config.h new file mode 100644 index 0000000..21a339a --- /dev/null +++ b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/config.h @@ -0,0 +1,134 @@ +/** + * @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 = "QTS_ATL_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *password = "Fayetteville123"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 25, 123); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 25, 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, 49, 0, "Total Ariflow"}, + {HR_FLOAT, 31, 0, "Airflow Effectiveness"}, + {HR_FLOAT, 33, 0, "Return Humidity"}, + {HR_FLOAT, 35, 0, "Return Air Temp"}, + {HR_FLOAT, 37, 0, "Return Dew Point"}, + {HR_FLOAT, 55, 0, "Supply Air Temp"}, + {HR_FLOAT, 27, 0, "Cooling Valve Output"}, + {HR_FLOAT, 29, 0, "Feedback Differential"}, + {HR, 23, 0, "Airflow Used"}, + {HR, 24, 0, "Available Airflow"}, + {HR_FLOAT, 47, 0, "Cooling Capacity"}, + {HR_FLOAT, 45, 0, "Net Sensible Cooling Capacity"}, + {HR_FLOAT, 43, 0, "Fan Time in Hrs"}, + {HR_FLOAT, 51, 0, "Differential Air Temp"}, + {HR_FLOAT, 39, 0, "Fan Speed"}, + {HR, 20, 0, "Heartbeat"}, + + {HR_FLOAT, 41, 0, "Air Temp Setpoint"}, + {HR_FLOAT, 25, 0, "Fan Speed Setpoint"}, + + {HR, 17, 0, "Pump Run Status"}, + {HR, 18, 0, "Pump Health"}, + {HR, 22, 0, "Pump High Float"}, + + {DI, 2, 0, "Common Alarm"}, + {DI, 12, 0, "Smoke Detected"}, + {DI, 13, 0, "Water Under Foot"}, + {DI, 14, 0, "Check Air Filter"}, + {DI, 15, 0, "Fan Issue"}, + {DI, 16, 0, "Alternate Power Source"}, + {DI, 8, 0, "Unit Status"}, + {DI, 7, 0, "Loss of Air Flow"}, + {DI, 8, 0, "Cooling State Input"}, + {DI, 6, 0, "Unit Local"}, + {HR, 4, 0, "Alarm Acknowledged"}, + + //{DI, 2, 0, "Operator Status (Input)"}, + //{COIL, 2, 0, "Operator Status (Output)"}, + //{DI, 2, 0, "Program Status (Input)"}, + //{COIL, 2, 0, "Program Status (Output)"}, + //{DI, 2, 0, "Running Status"}, + //{DI, 2, 0, "Not Ready Status"}, + //{DI, 2, 0, "Start Command (Input)"}, + //{COIL, 2, 0, "Start Command (Output)"}, + //{DI, 2, 0, "Stop Command (Input)"}, + //{COIL, 2, 0, "Stop Command (Output)"}, + //{DI, 2, 0, "Reset (Input)"}, + //{COIL, 2, 0, "Reset (Output)"}, + //{DI, 2, 0, "Start Command (Input)"}, + //{DI, 2, 0, "Stopped Status"}, + //{DI, 2, 0, "Error Status"}, + //{DI, 2, 0, "Not Ready Fail"}, + //{DI, 2, 0, "Starting Status"}, + //{DI, 2, 0, "Stopping Status"}, + // + //{HR_FLOAT, 2, 0, "Air Temp Setpoint (Output)"}, + //{HR_FLOAT, 2, 0, "Fan Speed Setpoint (Output)"}, + + +}; +//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/BMS/CRAH/CRAH_HTS_PLC_TCP/main.cpp b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/BMS/CRAH/CRAH_HTS_PLC_TCP/main.cpp @@ -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 +#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); + } +} From d792990bee9d5e07adbf2abfecca342faa7c3664 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Fri, 9 Jan 2026 10:47:04 -0600 Subject: [PATCH 46/51] q --- platformio.ini | 4 ++-- src/Base_TCP/config.h | 8 ++++---- src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/platformio.ini b/platformio.ini index 97e5cbb..7cf38b6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,10 +9,10 @@ [platformio] -default_envs = MVG_SC_EC_M505_TCP ; Select here the name of the configuration you want to download +default_envs = Base_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM26 +upload_port = COM15 [common_env_options] framework = arduino diff --git a/src/Base_TCP/config.h b/src/Base_TCP/config.h index 09bf37f..ca0d770 100644 --- a/src/Base_TCP/config.h +++ b/src/Base_TCP/config.h @@ -21,10 +21,10 @@ * @{ */ #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. */ + const char *ssid = "QTS_ATL_Arduino"; /**< @brief The SSID of the WiFi network. */ + const char *password = "Fayetteville123"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 25, 115); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 25, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp index 7d19437..e065339 100644 --- a/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp +++ b/src/EPMS/Breaker/BKR_ABB_XT_TCP/State_Standby.cpp @@ -98,6 +98,7 @@ void StandbyState::enterState(Equipment* equipment) { setPointValue(equipment, "kW", 0.0f); setPointValue(equipment, "kVA", 0.0f); setPointValue(equipment, "kWh", 0.0f); + setBitValue(equipment, "Alarm General", 0, false); } /** From be348deee3f9816f2f094a619e457b87869b1ceb Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Thu, 5 Feb 2026 14:43:19 -0600 Subject: [PATCH 47/51] CoolIT CDU equipment added to library --- platformio.ini | 8 +- src/BMS/CDU/CDU_CoolIT_Oracle_TCP/README.md | 33 +++++ .../CDU/CDU_CoolIT_Oracle_TCP/State_Fail.cpp | 81 +++++++++++ .../CDU_CoolIT_Oracle_TCP/State_Running.cpp | 136 ++++++++++++++++++ .../CDU_CoolIT_Oracle_TCP/State_Standby.cpp | 130 +++++++++++++++++ src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h | 129 +++++++++++++++++ src/BMS/CDU/CDU_CoolIT_Oracle_TCP/main.cpp | 86 +++++++++++ 7 files changed, 602 insertions(+), 1 deletion(-) create mode 100644 src/BMS/CDU/CDU_CoolIT_Oracle_TCP/README.md create mode 100644 src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Fail.cpp create mode 100644 src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Running.cpp create mode 100644 src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Standby.cpp create mode 100644 src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h create mode 100644 src/BMS/CDU/CDU_CoolIT_Oracle_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index bf5c678..1781736 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ [platformio] -default_envs = BKR_ABB_EMax2_TCP ; Select here the name of the configuration you want to download +default_envs = CDU_CoolIT_Oracle_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM19 @@ -261,3 +261,9 @@ extends = common_env_options build_flags = -D USE_MODBUS_IP, build_src_filter = -<*> + +[env:CDU_CoolIT_Oracle_TCP] +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/BMS/CDU/CDU_CoolIT_Oracle_TCP/README.md b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/README.md new file mode 100644 index 0000000..355156f --- /dev/null +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/README.md @@ -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 diff --git a/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Fail.cpp b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Fail.cpp new file mode 100644 index 0000000..8bc0385 --- /dev/null +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Fail.cpp @@ -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 +#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/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Running.cpp b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Running.cpp new file mode 100644 index 0000000..ce88f62 --- /dev/null +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Running.cpp @@ -0,0 +1,136 @@ +/** + * @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() { + addStrategy("TT01", new SingleValueStrategy(870.0F, 10.0f, 1000)); + addStrategy("TT02", new SingleValueStrategy(880.0F, 10.0f, 1000)); + addStrategy("TT31", new SingleValueStrategy(670.0F, 10.0f, 1000)); + addStrategy("TT41", new SingleValueStrategy(660.0F, 10.0f, 1000)); + addStrategy("PT01", new SingleValueStrategy(350.0F, 10.0f, 1000)); + addStrategy("PT02", new SingleValueStrategy(380.0F, 10.0f, 1000)); + addStrategy("PT31", new SingleValueStrategy(340.0F, 10.0f, 1000)); + addStrategy("PT41", new SingleValueStrategy(370.0F, 10.0f, 1000)); + addStrategy("PT32", new SingleValueStrategy(380.0F, 10.0f, 1000)); + addStrategy("PT42", new SingleValueStrategy(350.0F, 10.0f, 1000)); + addStrategy("PT21", new SingleValueStrategy(370.0F, 10.0f, 1000)); + addStrategy("PT11", new SingleValueStrategy(390.0F, 10.0f, 1000)); + addStrategy("AirTemp", new SingleValueStrategy(660.0F, 1.0f, 1000)); + addStrategy("DP31", new SingleValueStrategy(150.0F, 10.0f, 1000)); + addStrategy("DP41", new SingleValueStrategy(180.0F, 10.0f, 1000)); + addStrategy("DP", new SingleValueStrategy(160.0F, 10.0f, 1000)); + addStrategy("FL01", new SingleValueStrategy(7420.0F, 10.0f, 1000)); + addStrategy("P31_Speed", new SingleValueStrategy(300.0F, 10.0f, 1000)); + addStrategy("P41_Speed", new SingleValueStrategy(410.0F, 10.0f, 1000)); + addStrategy("F1_Speed", new SingleValueStrategy(180.0F, 10.0f, 1000)); + addStrategy("F2_Speed", new SingleValueStrategy(190.0F, 10.0f, 1000)); + addStrategy("F3_Speed", new SingleValueStrategy(170.0F, 10.0f, 1000)); + addStrategy("F4_Speed", new SingleValueStrategy(200.0F, 10.0f, 1000)); + addStrategy("F5_Speed", new SingleValueStrategy(250.0F, 10.0f, 1000)); + addStrategy("F6_Speed", new SingleValueStrategy(210.0F, 10.0f, 1000)); + addStrategy("F7_Speed", new SingleValueStrategy(200.0F, 10.0f, 1000)); + addStrategy("F8_Speed", new SingleValueStrategy(180.0F, 10.0f, 1000)); + addStrategy("AirTemp", new SingleValueStrategy(680.0f, 100.0f, 5000)); + addStrategy("Group_Flow", new SingleValueStrategy(7510.0F, 10.0f, 1000)); + addStrategy("Group_DP", new SingleValueStrategy(200.0F, 10.0f, 1000)); +} + +/** + * @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"); + float State_Ctrl = getPointValue(equipment, "Remote_Start"); + if (State_Ctrl == 0){ + return new StandbyState(); + } + + float TT01 = getPointValue(equipment, "TT01"); + float TT02 = getPointValue(equipment, "TT02"); + float TT31 = getPointValue(equipment, "TT31"); + float TT41 = getPointValue(equipment, "TT41"); + float PT01 = getPointValue(equipment, "PT01"); + float PT02 = getPointValue(equipment, "PT02"); + float PT31 = getPointValue(equipment, "PT31"); + float PT41 = getPointValue(equipment, "PT41"); + setPointValue(equipment, "TT01_TT02", (TT01 + TT02)/2.0f); + setPointValue(equipment, "TT31_TT41", (TT31 + TT41)/2.0f); + setPointValue(equipment, "PT01_PT02", (PT01 + PT02)/2.0f); + setPointValue(equipment, "PT31_PT41", (PT31 + PT41)/2.0f); + + // 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 + setPointValue(equipment, "Status", 1); +} + +/** + * @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/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Standby.cpp b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Standby.cpp new file mode 100644 index 0000000..c525d95 --- /dev/null +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/State_Standby.cpp @@ -0,0 +1,130 @@ +/** + * @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 + addStrategy("TT01", new SingleValueStrategy(870.0F, 10.0f, 1000)); + addStrategy("TT02", new SingleValueStrategy(870.0F, 10.0f, 1000)); + addStrategy("TT31", new SingleValueStrategy(870.0F, 10.0f, 1000)); + addStrategy("TT41", new SingleValueStrategy(870.0F, 10.0f, 1000)); + addStrategy("PT01", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT02", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT31", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT41", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT32", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT42", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT21", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("PT11", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("DP31", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("DP41", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("DP", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("FL01", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("AirTemp", new SingleValueStrategy(870.0F, 10.0f, 1000)); + addStrategy("P31_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("P41_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F1_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F2_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F3_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F4_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F5_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F6_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F7_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("F8_Speed", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("Group_Flow", new SingleValueStrategy(1.0F, 1.0f, 1000)); + addStrategy("Group_DP", new SingleValueStrategy(1.0F, 1.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* 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, "Remote_Start"); + if (State_Ctrl == 1){ + return new RunningState(); + } + float TT01 = getPointValue(equipment, "TT01"); + float TT02 = getPointValue(equipment, "TT02"); + float TT31 = getPointValue(equipment, "TT31"); + float TT41 = getPointValue(equipment, "TT41"); + float PT01 = getPointValue(equipment, "PT01"); + float PT02 = getPointValue(equipment, "PT02"); + float PT31 = getPointValue(equipment, "PT31"); + float PT41 = getPointValue(equipment, "PT41"); + setPointValue(equipment, "TT01_TT02", (TT01 + TT02)/2.0f); + setPointValue(equipment, "TT31_TT41", (TT31 + TT41)/2.0f); + setPointValue(equipment, "PT01_PT02", (PT01 + PT02)/2.0f); + setPointValue(equipment, "PT31_PT41", (PT31 + PT41)/2.0f); + // 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..."); + setPointValue(equipment, "Status", 0); +} + +/** + * @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/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h new file mode 100644 index 0000000..94179a2 --- /dev/null +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h @@ -0,0 +1,129 @@ +/** + * @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 = "Oracle_SA"; /**< @brief The SSID of the WiFi network. */ + const char *password = "Prime!123"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(192, 168, 1, 110); /**< @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, 0, 0, "Status"}, + {HR, 1, 0, "Group"}, + {HR, 2, 0, "TT01"}, + {HR, 3, 0, "TT02"}, + {HR, 4, 0, "TT31"}, + {HR, 5, 0, "TT41"}, + {HR, 6, 0, "PT01"}, + {HR, 7, 0, "PT02"}, + {HR, 8, 0, "PT31"}, + {HR, 9, 0, "PT41"}, + {HR, 10, 0, "PT32"}, + {HR, 11, 0, "PT42"}, + {HR, 12, 0, "PT21"}, + {HR, 13, 0, "PT11"}, + {HR, 14, 0, "TT01_TT02"}, + {HR, 15, 0, "TT31_TT41"}, + {HR, 16, 0, "PT01_PT02"}, + {HR, 17, 0, "PT31_PT41"}, + {HR, 18, 0, "DP31"}, + {HR, 19, 0, "DP41"}, + {HR, 20, 0, "DP"}, + {HR, 21, 0, "FL01"}, + {HR, 22, 0, "P31_Speed"}, + {HR, 23, 0, "P41_Speed"}, + {HR, 24, 0, "F1_Speed"}, + {HR, 25, 0, "F2_Speed"}, + {HR, 26, 0, "F3_Speed"}, + {HR, 27, 0, "F4_Speed"}, + {HR, 28, 0, "F5_Speed"}, + {HR, 29, 0, "F6_Speed"}, + {HR, 30, 0, "F7_Speed"}, + {HR, 31, 0, "F8_Speed"}, + {HR, 33, 0, "AirTemp"}, + {HR_FLOAT, 40, 0, "Group_Flow"}, + {HR_FLOAT, 42, 0, "Group_DP"}, + {HR, 44, 0, "Version"}, + {HR, 200, 0, "Temp_SP"}, + {HR, 201, 0, "DP_SP"}, + {HR, 202, 0, "Flow_SP"}, + + {COIL, 0, 0, "Alarm"}, + {COIL, 1, 0, "Alarm_Ack"}, + {COIL, 5, 0, "OvrPressure"}, + {COIL, 14, 0, "Ntwk_Fault"}, + {COIL, 15, 0, "Unit_Available"}, + {COIL, 33, 0, "OvrTemp"}, + {COIL, 86, 0, "LD01"}, + {COIL, 87, 0, "StpBtn"}, + {COIL, 131, 0, "Critical_Fault"}, + {COIL, 132, 0, "Power_Fault"}, + {COIL, 133, 0, "PLC_Fault"}, + {COIL, 200, 0, "Remote_Start"}, + +}; +//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/BMS/CDU/CDU_CoolIT_Oracle_TCP/main.cpp b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/main.cpp @@ -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 +#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); + } +} From 09be54e33098c47b7adbbe12a71ad88e32e0779c Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Thu, 12 Feb 2026 11:35:04 -0600 Subject: [PATCH 48/51] RPP program added --- platformio.ini | 11 +- src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h | 4 +- src/EPMS/RPP/RPP_Cortex_TCP/README.md | 33 +++ src/EPMS/RPP/RPP_Cortex_TCP/State_Fail.cpp | 81 +++++++ src/EPMS/RPP/RPP_Cortex_TCP/State_Running.cpp | 99 ++++++++ src/EPMS/RPP/RPP_Cortex_TCP/State_Standby.cpp | 224 ++++++++++++++++++ src/EPMS/RPP/RPP_Cortex_TCP/config.h | 219 +++++++++++++++++ src/EPMS/RPP/RPP_Cortex_TCP/main.cpp | 86 +++++++ 8 files changed, 753 insertions(+), 4 deletions(-) create mode 100644 src/EPMS/RPP/RPP_Cortex_TCP/README.md create mode 100644 src/EPMS/RPP/RPP_Cortex_TCP/State_Fail.cpp create mode 100644 src/EPMS/RPP/RPP_Cortex_TCP/State_Running.cpp create mode 100644 src/EPMS/RPP/RPP_Cortex_TCP/State_Standby.cpp create mode 100644 src/EPMS/RPP/RPP_Cortex_TCP/config.h create mode 100644 src/EPMS/RPP/RPP_Cortex_TCP/main.cpp diff --git a/platformio.ini b/platformio.ini index 1781736..82ff56a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ [platformio] -default_envs = CDU_CoolIT_Oracle_TCP ; Select here the name of the configuration you want to download +default_envs = RPP_Cortex_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM19 @@ -266,4 +266,11 @@ 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:RPP_Cortex_TCP] +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/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h index 94179a2..9112a8c 100644 --- a/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h @@ -23,8 +23,8 @@ #include const char *ssid = "Oracle_SA"; /**< @brief The SSID of the WiFi network. */ const char *password = "Prime!123"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(192, 168, 1, 110); /**< @brief The static IP address for the device. */ - IPAddress gateway(192, 168, 1, 1); /**< @brief The gateway IP address. */ + IPAddress local_IP(172, 17, 38, 22); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 38, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ ModbusIP mb; diff --git a/src/EPMS/RPP/RPP_Cortex_TCP/README.md b/src/EPMS/RPP/RPP_Cortex_TCP/README.md new file mode 100644 index 0000000..355156f --- /dev/null +++ b/src/EPMS/RPP/RPP_Cortex_TCP/README.md @@ -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 diff --git a/src/EPMS/RPP/RPP_Cortex_TCP/State_Fail.cpp b/src/EPMS/RPP/RPP_Cortex_TCP/State_Fail.cpp new file mode 100644 index 0000000..8bc0385 --- /dev/null +++ b/src/EPMS/RPP/RPP_Cortex_TCP/State_Fail.cpp @@ -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 +#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/RPP/RPP_Cortex_TCP/State_Running.cpp b/src/EPMS/RPP/RPP_Cortex_TCP/State_Running.cpp new file mode 100644 index 0000000..5b5350c --- /dev/null +++ b/src/EPMS/RPP/RPP_Cortex_TCP/State_Running.cpp @@ -0,0 +1,99 @@ +/** + * @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() { + addStrategy("TT01", new SingleValueStrategy(870.0F, 10.0f, 1000)); + +} + +/** + * @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"); + float State_Ctrl = getPointValue(equipment, "Remote_Start"); + if (State_Ctrl == 0){ + return new StandbyState(); + } + + float TT01 = getPointValue(equipment, "TT01"); + float TT02 = getPointValue(equipment, "TT02"); + setPointValue(equipment, "TT01_TT02", (TT01 + TT02)/2.0f); + + // 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 + setPointValue(equipment, "Status", 1); +} + +/** + * @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/RPP/RPP_Cortex_TCP/State_Standby.cpp b/src/EPMS/RPP/RPP_Cortex_TCP/State_Standby.cpp new file mode 100644 index 0000000..cf74d5b --- /dev/null +++ b/src/EPMS/RPP/RPP_Cortex_TCP/State_Standby.cpp @@ -0,0 +1,224 @@ +/** + * @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 + addStrategy("In_freq", new SingleValueStrategy(60.0F, 1.0f, 1000)); + addStrategy("InV_L1N", new SingleValueStrategy(220.0F, 1.0f, 1000)); + addStrategy("InV_L2N", new SingleValueStrategy(220.0F, 1.0f, 1000)); + addStrategy("InV_L3N", new SingleValueStrategy(220.0F, 1.0f, 1000)); + addStrategy("InV_L12", new SingleValueStrategy(480.0F, 1.0f, 1000)); + addStrategy("InV_L23", new SingleValueStrategy(480.0F, 1.0f, 1000)); + addStrategy("InV_L31", new SingleValueStrategy(480.0F, 1.0f, 1000)); + addStrategy("InTHD_L1N", new SingleValueStrategy(2.5F, 0.5f, 1000)); + addStrategy("InTHD_L2N", new SingleValueStrategy(3.1F, 0.5f, 1000)); + addStrategy("InTHD_L3N", new SingleValueStrategy(2.4F, 0.5f, 1000)); + addStrategy("InTHD_L1_1st", new SingleValueStrategy(2.4F, 0.2f, 1000)); + addStrategy("InTHD_L1_3rd", new SingleValueStrategy(2.1F, 0.2f, 1000)); + addStrategy("InTHD_L1_5th", new SingleValueStrategy(1.9F, 0.2f, 1000)); + addStrategy("InTHD_L1_7th", new SingleValueStrategy(2.1F, 0.2f, 1000)); + addStrategy("InTHD_L1_9th", new SingleValueStrategy(1.8F, 0.2f, 1000)); + addStrategy("InTHD_L2_1st", new SingleValueStrategy(2.3F, 0.2f, 1000)); + addStrategy("InTHD_L2_3rd", new SingleValueStrategy(2.2F, 0.2f, 1000)); + addStrategy("InTHD_L2_5th", new SingleValueStrategy(2.4F, 0.2f, 1000)); + addStrategy("InTHD_L2_7th", new SingleValueStrategy(2.5F, 0.2f, 1000)); + addStrategy("InTHD_L2_9th", new SingleValueStrategy(2.6F, 0.2f, 1000)); + addStrategy("InTHD_L3_1st", new SingleValueStrategy(2.2F, 0.2f, 1000)); + addStrategy("InTHD_L3_3rd", new SingleValueStrategy(2.3F, 0.2f, 1000)); + addStrategy("InTHD_L3_5th", new SingleValueStrategy(2.1F, 0.2f, 1000)); + addStrategy("InTHD_L3_7th", new SingleValueStrategy(2.4F, 0.2f, 1000)); + addStrategy("InTHD_L3_9th", new SingleValueStrategy(2.5F, 0.2f, 1000)); + addStrategy("InTHD_L12", new SingleValueStrategy(3.1F, 0.2f, 1000)); + addStrategy("InTHD_L23", new SingleValueStrategy(2.1F, 0.2f, 1000)); + addStrategy("InTHD_L31", new SingleValueStrategy(1.8F, 0.2f, 1000)); + + addStrategy("CB1_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB2_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB3_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB4_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB5_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB6_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB7_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB8_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB9_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB10_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB11_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB12_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB13_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB14_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB15_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + addStrategy("CB16_kW", new SingleValueStrategy(3.1F, 3.0f, 1000)); + + addStrategy("MainCB_PF", new SingleValueStrategy(0.9F, 0.05f, 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* StandbyState::update(Equipment* equipment) { + // STATE control, add conditions if change to a different state is needed + Serial.println("Standby update function"); + + // Calculate Avergae for voltage LN points + float InV_L1N = getPointValue(equipment, "InV_L1N"); + float InV_L2N = getPointValue(equipment, "InV_L2N"); + float InV_L3N = getPointValue(equipment, "InV_L3N"); + setPointValue(equipment, "InV_LN_avg", (InV_L1N + InV_L2N + InV_L3N)/3.0f); + // Calculate Avergae for voltage LL points + float InV_L12 = getPointValue(equipment, "InV_L12"); + float InV_L23 = getPointValue(equipment, "InV_L23"); + float InV_L31 = getPointValue(equipment, "InV_L31"); + setPointValue(equipment, "InV_LL_avg", (InV_L12 + InV_L23 + InV_L31)/3.0f); + + + for (int i = 1; i <= 16; i++) { + std::string cb_name = "CB" + std::to_string(i); + std::string kw_name = cb_name + "_kW"; + std::string max_kw_name = cb_name + "_max_kW"; + std::string max_current_name = cb_name + "_maxCurrent"; + + float cb_value = getPointValue(equipment, cb_name.c_str()); + if (cb_value == 1.0f){ + float kw = 350.0f; + Strategy_Behavior* svs_cb_kW = getStrategy(kw_name.c_str()); + static_cast(svs_cb_kW)->setSetpoint(kw); + + float in_v_ll_avg = getPointValue(equipment, "InV_LL_avg"); + float current = (kw*1000.0f)/(in_v_ll_avg*1.73f); + setPointValue(equipment, max_current_name.c_str(), current); + + float max_kw = getPointValue(equipment, max_kw_name.c_str()); + if (kw > max_kw){ + setPointValue(equipment, max_kw_name.c_str(), kw); + } + + float max_current = getPointValue(equipment, max_current_name.c_str()); + if (current > max_current){ + setPointValue(equipment, max_current_name.c_str(), current); + } + } + + + } + + float mainCB_total_kW = 0.0f; + float mainCB_maxCurrent = 0.0f; + float mainCB_neutralCurrent = 0.0f; + float mainCB_maxTotalKw = 0.0f; + float mainCB_maxTotalCurrent = 0.0f; + for (int i = 1; i <= 16; i++) { + std::string kw_name = "CB" + std::to_string(i) + "_kW"; + std::string max_current_name = "CB" + std::to_string(i) + "_maxCurrent"; + mainCB_total_kW += getPointValue(equipment, kw_name.c_str()); + mainCB_maxCurrent += getPointValue(equipment, max_current_name.c_str()); + float max_kw = getPointValue(equipment, ("CB" + std::to_string(i) + "_max_kW").c_str()); + if (max_kw > mainCB_maxTotalKw) { + mainCB_maxTotalKw = max_kw; + } + float max_current = getPointValue(equipment, max_current_name.c_str()); + if (max_current > mainCB_maxTotalCurrent) { + mainCB_maxTotalCurrent = max_current; + } + } + + float mainCB_PF = getPointValue(equipment, "MainCB_PF"); + setPointValue(equipment, "MainCB_Total_kW", mainCB_total_kW); + setPointValue(equipment, "MainCB_maxCurrent", mainCB_maxCurrent); + setPointValue(equipment, "MainCB_neutralCurrent", mainCB_neutralCurrent); + setPointValue(equipment, "MainCB_maxTotalkW", mainCB_maxTotalKw); + setPointValue(equipment, "MainCB_maxTotalCurrent", mainCB_maxTotalCurrent); + + setPointValue(equipment, "MainCB_L1_kW", mainCB_total_kW); + setPointValue(equipment, "MainCB_L1_kVA", mainCB_total_kW*1.3f); + setPointValue(equipment, "MainCB_L1_Current", mainCB_maxCurrent); + setPointValue(equipment, "MainCB_L1_PF", mainCB_PF); + setPointValue(equipment, "MainCB_L1_max_kW", mainCB_maxTotalKw); + setPointValue(equipment, "MainCB_L1_max_current", mainCB_maxTotalCurrent); + + setPointValue(equipment, "MainCB_L2_kW", mainCB_total_kW); + setPointValue(equipment, "MainCB_L2_kVA", mainCB_total_kW*1.3f); + setPointValue(equipment, "MainCB_L2_Current", mainCB_maxCurrent); + setPointValue(equipment, "MainCB_L2_PF", mainCB_PF); + setPointValue(equipment, "MainCB_L2_max_kW", mainCB_maxTotalKw); + setPointValue(equipment, "MainCB_L2_max_current", mainCB_maxTotalCurrent); + + setPointValue(equipment, "MainCB_L3_kW", mainCB_total_kW); + setPointValue(equipment, "MainCB_L3_kVA", mainCB_total_kW*1.3f); + setPointValue(equipment, "MainCB_L3_Current", mainCB_maxCurrent); + setPointValue(equipment, "MainCB_L3_PF", mainCB_PF); + setPointValue(equipment, "MainCB_L3_max_kW", mainCB_maxTotalKw); + setPointValue(equipment, "MainCB_L3_max_current", mainCB_maxTotalCurrent); + + + // 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..."); + setPointValue(equipment, "Status", 0); +} + +/** + * @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..."); +} + diff --git a/src/EPMS/RPP/RPP_Cortex_TCP/config.h b/src/EPMS/RPP/RPP_Cortex_TCP/config.h new file mode 100644 index 0000000..a1de0d7 --- /dev/null +++ b/src/EPMS/RPP/RPP_Cortex_TCP/config.h @@ -0,0 +1,219 @@ +/** + * @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 = "Oracle_SA"; /**< @brief The SSID of the WiFi network. */ + const char *password = "Prime!123"; /**< @brief The password for the WiFi network. */ + IPAddress local_IP(172, 17, 38, 72); /**< @brief The static IP address for the device. */ + IPAddress gateway(172, 17, 38, 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, 2046, 0, "CB1"}, + {HR, 2047, 0, "CB2"}, + {HR, 2048, 0, "CB3"}, + {HR, 2049, 0, "CB4"}, + {HR, 2050, 0, "CB5"}, + {HR, 2051, 0, "CB6"}, + {HR, 2052, 0, "CB7"}, + {HR, 2053, 0, "CB8"}, + {HR, 2054, 0, "CB9"}, + {HR, 2055, 0, "CB10"}, + {HR, 2056, 0, "CB11"}, + {HR, 2057, 0, "CB12"}, + {HR, 2058, 0, "CB13"}, + {HR, 2059, 0, "CB14"}, + {HR, 2060, 0, "CB15"}, + {HR, 2061, 0, "CB16"}, + {HR_FLOAT, 9000, 0, "In_freq"}, + {HR_FLOAT, 9002, 0, "InV_L1N"}, + {HR_FLOAT, 9004, 0, "InV_L2N"}, + {HR_FLOAT, 9006, 0, "InV_L3N"}, + {HR_FLOAT, 9008, 0, "InV_LN_avg"}, + {HR_FLOAT, 9010, 0, "InV_L12"}, + {HR_FLOAT, 9012, 0, "InV_L23"}, + {HR_FLOAT, 9014, 0, "InV_L31"}, + {HR_FLOAT, 9016, 0, "InV_LL_avg"}, + {HR_FLOAT, 9018, 0, "InTHD_L1N"}, + {HR_FLOAT, 9020, 0, "InTHD_L2N"}, + {HR_FLOAT, 9022, 0, "InTHD_L3N"}, + {HR_FLOAT, 9036, 0, "InTHD_L1_1st"}, + {HR_FLOAT, 9040, 0, "InTHD_L1_3rd"}, + {HR_FLOAT, 9044, 0, "InTHD_L1_5th"}, + {HR_FLOAT, 9048, 0, "InTHD_L1_7th"}, + {HR_FLOAT, 9052, 0, "InTHD_L1_9th"}, + {HR_FLOAT, 9162, 0, "InTHD_L2_1st"}, + {HR_FLOAT, 9166, 0, "InTHD_L2_3rd"}, + {HR_FLOAT, 9170, 0, "InTHD_L2_5th"}, + {HR_FLOAT, 9174, 0, "InTHD_L2_7th"}, + {HR_FLOAT, 9178, 0, "InTHD_L2_9th"}, + {HR_FLOAT, 9288, 0, "InTHD_L3_1st"}, + {HR_FLOAT, 9292, 0, "InTHD_L3_3rd"}, + {HR_FLOAT, 9296, 0, "InTHD_L3_5th"}, + {HR_FLOAT, 9300, 0, "InTHD_L3_7th"}, + {HR_FLOAT, 9304, 0, "InTHD_L3_9th"}, + {HR_FLOAT, 9018, 0, "InTHD_L12"}, + {HR_FLOAT, 9020, 0, "InTHD_L23"}, + {HR_FLOAT, 9022, 0, "InTHD_L31"}, + + {HR_FLOAT, 13456, 0, "CB1_kW"}, + {HR_FLOAT, 13460, 0, "CB2_kW"}, + {HR_FLOAT, 13464, 0, "CB3_kW"}, + {HR_FLOAT, 13468, 0, "CB4_kW"}, + {HR_FLOAT, 13472, 0, "CB5_kW"}, + {HR_FLOAT, 13476, 0, "CB6_kW"}, + {HR_FLOAT, 13480, 0, "CB7_kW"}, + {HR_FLOAT, 13484, 0, "CB8_kW"}, + {HR_FLOAT, 13488, 0, "CB9_kW"}, + {HR_FLOAT, 13492, 0, "CB10_kW"}, + {HR_FLOAT, 13496, 0, "CB11_kW"}, + {HR_FLOAT, 13500, 0, "CB12_kW"}, + {HR_FLOAT, 13504, 0, "CB13_kW"}, + {HR_FLOAT, 13508, 0, "CB14_kW"}, + {HR_FLOAT, 13512, 0, "CB15_kW"}, + {HR_FLOAT, 13516, 0, "CB16_kW"}, + + {HR_FLOAT, 14608, 0, "CB1_Current"}, + {HR_FLOAT, 14612, 0, "CB2_Current"}, + {HR_FLOAT, 14616, 0, "CB3_Current"}, + {HR_FLOAT, 14620, 0, "CB4_Current"}, + {HR_FLOAT, 14624, 0, "CB5_Current"}, + {HR_FLOAT, 14628, 0, "CB6_Current"}, + {HR_FLOAT, 14632, 0, "CB7_Current"}, + {HR_FLOAT, 14636, 0, "CB8_Current"}, + {HR_FLOAT, 14640, 0, "CB9_Current"}, + {HR_FLOAT, 14644, 0, "CB10_Current"}, + {HR_FLOAT, 14648, 0, "CB11_Current"}, + {HR_FLOAT, 14652, 0, "CB12_Current"}, + {HR_FLOAT, 14656, 0, "CB13_Current"}, + {HR_FLOAT, 14660, 0, "CB14_Current"}, + {HR_FLOAT, 14664, 0, "CB15_Current"}, + {HR_FLOAT, 14668, 0, "CB16_Current"}, + + {HR_FLOAT, 16912, 0, "CB1_max_kW"}, + {HR_FLOAT, 16916, 0, "CB2_max_kW"}, + {HR_FLOAT, 16920, 0, "CB3_max_kW"}, + {HR_FLOAT, 16924, 0, "CB4_max_kW"}, + {HR_FLOAT, 16928, 0, "CB5_max_kW"}, + {HR_FLOAT, 16932, 0, "CB6_max_kW"}, + {HR_FLOAT, 16936, 0, "CB7_max_kW"}, + {HR_FLOAT, 16940, 0, "CB8_max_kW"}, + {HR_FLOAT, 16944, 0, "CB9_max_kW"}, + {HR_FLOAT, 16948, 0, "CB10_max_kW"}, + {HR_FLOAT, 16952, 0, "CB11_max_kW"}, + {HR_FLOAT, 16956, 0, "CB12_max_kW"}, + {HR_FLOAT, 16960, 0, "CB13_max_kW"}, + {HR_FLOAT, 16964, 0, "CB14_max_kW"}, + {HR_FLOAT, 16968, 0, "CB15_max_kW"}, + {HR_FLOAT, 16972, 0, "CB16_max_kW"}, + + {HR_FLOAT, 17296, 0, "CB1_maxCurrent"}, + {HR_FLOAT, 17300, 0, "CB2_maxCurrent"}, + {HR_FLOAT, 17304, 0, "CB3_maxCurrent"}, + {HR_FLOAT, 17308, 0, "CB4_maxCurrent"}, + {HR_FLOAT, 17312, 0, "CB5_maxCurrent"}, + {HR_FLOAT, 17316, 0, "CB6_maxCurrent"}, + {HR_FLOAT, 17320, 0, "CB7_maxCurrent"}, + {HR_FLOAT, 17324, 0, "CB8_maxCurrent"}, + {HR_FLOAT, 17328, 0, "CB9_maxCurrent"}, + {HR_FLOAT, 17332, 0, "CB10_maxCurrent"}, + {HR_FLOAT, 17336, 0, "CB11_maxCurrent"}, + {HR_FLOAT, 17340, 0, "CB12_maxCurrent"}, + {HR_FLOAT, 17344, 0, "CB13_maxCurrent"}, + {HR_FLOAT, 17348, 0, "CB14_maxCurrent"}, + {HR_FLOAT, 17352, 0, "CB15_maxCurrent"}, + {HR_FLOAT, 17356, 0, "CB16_maxCurrent"}, + + {HR_FLOAT, 40058, 0, "MainCB_Total_kW"}, + {HR_FLOAT, 40064, 0, "MainCB_maxCurrent"}, + {HR_FLOAT, 40068, 0, "MainCB_neutralCurrent"}, + {HR_FLOAT, 40070, 0, "MainCB_PF"}, + {HR_FLOAT, 40074, 0, "MainCB_maxTotalkW"}, + {HR_FLOAT, 40076, 0, "MainCB_maxTotalCurrent"}, + + {HR_FLOAT, 40108, 0, "MainCB_L1_kW"}, + {HR_FLOAT, 40112, 0, "MainCB_L1_kVA"}, + {HR_FLOAT, 40114, 0, "MainCB_L1_Current"}, + {HR_FLOAT, 40116, 0, "MainCB_L1_PF"}, + {HR_FLOAT, 40126, 0, "MainCB_L1_max_kW"}, + {HR_FLOAT, 40128, 0, "MainCB_L1_max_current"}, + + {HR_FLOAT, 40158, 0, "MainCB_L2_kW"}, + {HR_FLOAT, 40162, 0, "MainCB_L2_kVA"}, + {HR_FLOAT, 40164, 0, "MainCB_L2_Current"}, + {HR_FLOAT, 40166, 0, "MainCB_L2_PF"}, + {HR_FLOAT, 40176, 0, "MainCB_L2_max_kW"}, + {HR_FLOAT, 40178, 0, "MainCB_L2_max_current"}, + + {HR_FLOAT, 40208, 0, "MainCB_L3_kW"}, + {HR_FLOAT, 40212, 0, "MainCB_L3_kVA"}, + {HR_FLOAT, 40214, 0, "MainCB_L3_Current"}, + {HR_FLOAT, 40216, 0, "MainCB_L3_PF"}, + {HR_FLOAT, 40226, 0, "MainCB_L3_max_kW"}, + {HR_FLOAT, 40228, 0, "MainCB_L3_max_current"}, + +}; +//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/RPP/RPP_Cortex_TCP/main.cpp b/src/EPMS/RPP/RPP_Cortex_TCP/main.cpp new file mode 100644 index 0000000..286a98c --- /dev/null +++ b/src/EPMS/RPP/RPP_Cortex_TCP/main.cpp @@ -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 +#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); + } +} From c075b2c0ea526f2eee8936c388a984244bba5cb2 Mon Sep 17 00:00:00 2001 From: DohnJev18 Date: Thu, 12 Feb 2026 11:54:36 -0600 Subject: [PATCH 49/51] upload upload --- platformio.ini | 4 ++-- src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 8a950e5..d1e4db7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,10 +9,10 @@ [platformio] -default_envs = RPP_Cortex_TCP ; Select here the name of the configuration you want to download +default_envs = CDU_CoolIT_Oracle_TCP ; Select here the name of the configuration you want to download [env] -upload_port = COM19 +upload_port = COM3 [common_env_options] framework = arduino diff --git a/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h index 9112a8c..fbd0547 100644 --- a/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h +++ b/src/BMS/CDU/CDU_CoolIT_Oracle_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "Oracle_SA"; /**< @brief The SSID of the WiFi network. */ const char *password = "Prime!123"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 38, 22); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 38, 23); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 38, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ From e1d43e9de8cfce7cf43f05bd59ce665dc3abf6ee Mon Sep 17 00:00:00 2001 From: DohnJev18 Date: Mon, 16 Feb 2026 16:03:09 -0600 Subject: [PATCH 50/51] changes changes --- platformio.ini | 2 +- src/EPMS/RPP/RPP_Cortex_TCP/config.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index d1e4db7..e7b43cc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ [platformio] -default_envs = CDU_CoolIT_Oracle_TCP ; Select here the name of the configuration you want to download +default_envs = RPP_Cortex_TCP ; Select here the name of the configuration you want to download [env] upload_port = COM3 diff --git a/src/EPMS/RPP/RPP_Cortex_TCP/config.h b/src/EPMS/RPP/RPP_Cortex_TCP/config.h index a1de0d7..ac5d0bf 100644 --- a/src/EPMS/RPP/RPP_Cortex_TCP/config.h +++ b/src/EPMS/RPP/RPP_Cortex_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "Oracle_SA"; /**< @brief The SSID of the WiFi network. */ const char *password = "Prime!123"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 38, 72); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 38, 51); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 38, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */ From 1226c4541803d174cabca9dab14595f609b11b0f Mon Sep 17 00:00:00 2001 From: RobertJDavis Date: Tue, 24 Feb 2026 15:34:17 -0700 Subject: [PATCH 51/51] Update config.h --- src/BMS/CRAH/CRAH_UMAS_TCP/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h index 6ef768a..0fac917 100644 --- a/src/BMS/CRAH/CRAH_UMAS_TCP/config.h +++ b/src/BMS/CRAH/CRAH_UMAS_TCP/config.h @@ -23,7 +23,7 @@ #include const char *ssid = "ArduinoWifiB"; /**< @brief The SSID of the WiFi network. */ const char *password = "123abc456"; /**< @brief The password for the WiFi network. */ - IPAddress local_IP(172, 17, 32, 49); /**< @brief The static IP address for the device. */ + IPAddress local_IP(172, 17, 32, 232); /**< @brief The static IP address for the device. */ IPAddress gateway(172, 17, 32, 1); /**< @brief The gateway IP address. */ IPAddress subnet(255, 255, 255, 0); /**< @brief The subnet mask. */