From 5ab69c81ccb79e8ee7a34a918e0a3192d468ba43 Mon Sep 17 00:00:00 2001 From: Emmanuel HC Date: Thu, 23 Oct 2025 22:03:58 -0500 Subject: [PATCH] New method to set reset bits --- lib/Core/States/State.h | 49 +++++++++++++++++++ .../PDU_Maverick_Power_TCP/State_Running.cpp | 23 ++++++++- src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h | 11 ++++- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/lib/Core/States/State.h b/lib/Core/States/State.h index 9af86bf..805d93d 100644 --- a/lib/Core/States/State.h +++ b/lib/Core/States/State.h @@ -87,6 +87,15 @@ protected: * @param strategy A pointer to the Strategy_Behavior object. The State takes ownership. */ void addStrategy(const std::string& pointDescription, Strategy_Behavior* strategy); + + /** + * @brief Modify specifyc bits of a Modbus point in this state. + * @param equipment Pointer to the Equipment instance. + * @param pointName The description key of the Modbus point to write to. + * @param bitPosition The position to which the function will write to. + * @param state The new state of the selected bit. + */ + void setBitValue(Equipment* equipment, const std::string& pointName, int bitPosition, bool state); /** * @brief returns a behavior strategy for a specific Modbus point in this state. * @param pointDescription The description of the Modbus point your need to get. @@ -218,4 +227,44 @@ void State::_applyStrategies(Equipment* equipment) { } } + +/** + * @brief Controls a specific bit within an integer Modbus word (like a Holding or Input Register). + * + * This function bypasses the standard float logic to perform direct bit manipulation. + * + * @param equipment Pointer to the Equipment instance. + * @param pointName The description key of the Modbus point to modify. + * @param bitPosition The 0-based index of the bit to set/clear (0-15 for a 16-bit word). + * @param state If true, the bit is set (to 1); if false, the bit is cleared (to 0). + */ +template +void State::setBitValue(Equipment* equipment, const std::string& pointName, int bitPosition, bool state) { + Modbus_Point* point = equipment->getModbus_Point(pointName); + + // Safety check: Ensure the point exists and isn't a decorated multi-word type (Float or Long) + // Note: Standard 16-bit Hreg/Ireg will return PointType::GENERIC. + if (!point || point->getType() != PointType::GENERIC || bitPosition < 0 || bitPosition > 15) { + // You can add an error logging statement here if needed, like Serial.printf(...) + return; + } + + // 1. Get the current integer value directly from the point + int currentValue = point->getValue(); + + // 2. Create the bit mask + // '1 << bitPosition' shifts a 1 to the position we want to affect + int mask = 1 << bitPosition; + + if (state) { + // 3. Set the bit (make it 1): Use the bitwise OR operator + currentValue |= mask; + } else { + // 3. Clear the bit (make it 0): Use the bitwise AND operator with the NOT (inverse) of the mask + currentValue &= ~mask; + } + + // 4. Write the new integer value back + point->setValue(currentValue); +} #endif 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 57a63d4..153ba0f 100644 --- a/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp +++ b/src/EPMS/PDU/PDU_Maverick_Power_TCP/State_Running.cpp @@ -105,6 +105,11 @@ RunningState::RunningState() { tag = cb + "_V31"; addStrategy(tag, new SingleValueStrategy(0.0f, 30.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)); } /** @@ -142,7 +147,7 @@ State* RunningState::update(Equipment* equipment) cb_count += 1.0f; } } - + int cb_num = 0; for (const std::string& cb : cbs) { std::string tag = ""; Strategy_Behavior* strategy = nullptr; @@ -155,7 +160,13 @@ State* RunningState::update(Equipment* equipment) float cb_load = total_load / cb_count; if (cb_status == 1.0f){ - + setBitValue(equipment, "CB_Status", cb_num, true); + 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); @@ -214,6 +225,13 @@ State* RunningState::update(Equipment* equipment) }else{ + 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); @@ -270,6 +288,7 @@ State* RunningState::update(Equipment* equipment) tag = cb + "_L3KVar"; setPointValue(equipment, tag, total_load*0.0f); } + cb_num++; } // Apply any strategies defined for the standby state _applyStrategies(equipment); diff --git a/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h b/src/EPMS/PDU/PDU_Maverick_Power_TCP/config.h index ce064c9..db59a4b 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. */ @@ -557,6 +557,15 @@ modbusMap mb_map[] = { {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" }, + + {IR, 1150, 0, "CB_Status" }, + {IR, 1151, 0, "CB_Tripped" }, + }; //Size of modbus map used in FOR cycles, automatically calculated.