From 6bac7a5e7b352124d5e1be9063cc96379b475650 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Apr 2026 15:46:07 +0200 Subject: [PATCH 01/22] spliting in progress --- CMakeLists.txt | 67 +++++++++++++++---- .../ePowerSwitchEquipment.cpp} | 50 +------------- src/device/ePowerSwitchEquipment.h | 49 ++++++++++++++ .../device/ePowerSwitchEquipmentConfig.h | 3 - src/frontend/ePowerSwitchFrontend.cpp | 49 ++++++++++++++ src/frontend/ePowerSwitchFrontend.h | 17 +++++ src/frontend/ePowerSwitchFrontendConfig.h | 7 ++ 7 files changed, 179 insertions(+), 63 deletions(-) rename src/{ePowerSwitchFront.cpp => device/ePowerSwitchEquipment.cpp} (76%) create mode 100644 src/device/ePowerSwitchEquipment.h rename include/ePowerSwitchConfig.h => src/device/ePowerSwitchEquipmentConfig.h (75%) create mode 100644 src/frontend/ePowerSwitchFrontend.cpp create mode 100644 src/frontend/ePowerSwitchFrontend.h create mode 100644 src/frontend/ePowerSwitchFrontendConfig.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d543d87..cb5ecd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.03) -project(ePowerSwitchFront VERSION 1.0) +project(ePowerSwitchFrontend VERSION 1.0) add_subdirectory(submodule/mepicsca) @@ -44,20 +44,32 @@ set(LIBS find_package(Midas REQUIRED) -add_executable(ePowerSwitchFront - src/ePowerSwitchFront.cpp +################################################################################ +## Device Library +################################################################################ + +add_library( + ePowerSwitchEquipment + src/device/ePowerSwitchEquipment.cpp ) set_property( TARGET - ePowerSwitchFront + ePowerSwitchEquipment PROPERTY CXX_STANDARD 17 ) +target_link_libraries( + ePowerSwitchEquipment + PRIVATE + midas::mfe + m_epics_ca + ${LIBS} +) target_include_directories( - ePowerSwitchFront + ePowerSwitchEquipment PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE @@ -68,15 +80,46 @@ target_include_directories( ${EPICSSYS}/include/compiler/clang ) -target_link_libraries(ePowerSwitchFront + + +################################################################################ +## Frontend +################################################################################ + +add_executable(ePowerSwitchFrontend + src/frontend/ePowerSwitchFrontend.cpp +) + +set_property( + TARGET + ePowerSwitchFrontend + PROPERTY + CXX_STANDARD 17 +) + + +target_include_directories( + ePowerSwitchFrontend + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE + ${EPICSSYS}/include + ${EPICSSYS}/include/os/Linux + ${EPICSSYS}/include/os/Darwin + ${EPICSSYS}/include/compiler/gcc + ${EPICSSYS}/include/compiler/clang +) + +target_link_libraries( + ePowerSwitchFrontend + PRIVATE + ePowerSwitchEquipment midas::mfe m_epics_ca ${LIBS} ) - -install( - TARGETS - ePowerSwitchFront - RUNTIME DESTINATION bin -) +# install( +# TARGETS +# ePowerSwitchFrontend +# RUNTIME DESTINATION bin +# ) diff --git a/src/ePowerSwitchFront.cpp b/src/device/ePowerSwitchEquipment.cpp similarity index 76% rename from src/ePowerSwitchFront.cpp rename to src/device/ePowerSwitchEquipment.cpp index 79ca831..42ff785 100644 --- a/src/ePowerSwitchFront.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -1,6 +1,5 @@ -#include "../include/ePowerSwitchFront.h" -#include "../include/ePowerSwitchConfig.h" -#include "m_epics_ca.h" +#include "ePowerSwitchEquipment.h" +#include "ePowerSwitchEquipmentConfig.h" #include "tmfe.h" #include @@ -17,45 +16,6 @@ std::string format(std::string str, int value) { return ss.str(); } -int main(int argc, char *argv[]) { - - if (argv[0][0] == '.') { - TMFE::Instance()->Msg(MERROR, __FUNCTION__, - "Relative paths are strongly discouraged; " - "please use an absolute path."); - } - - std::string frontendName; - std::string equipmentName; - - if (argc == 1) { - frontendName = DEFAULT_FRONTEND_NAME; - TMFE::Instance()->Msg(MINFO, __FUNCTION__, - "No frontend name provided; %s will be used", - DEFAULT_FRONTEND_NAME); - equipmentName = DEFAULT_EQUIPMENT_NAME; - TMFE::Instance()->Msg(MINFO, __FUNCTION__, - "No equipment name provided; %s will be used", - DEFAULT_EQUIPMENT_NAME); - } - if (argc == 2) { - frontendName = std::string(argv[1]); - argv++; - argc--; - TMFE::Instance()->Msg(MINFO, __FUNCTION__, - "No equipment name provided; %s will be use", - DEFAULT_EQUIPMENT_NAME); - } else if (argc == 3) { - frontendName = std::string(argv[1]); - equipmentName = std::string(argv[2]); - argv += 2; - argc -= 2; - } - - auto front = new ePowerSwitchFrontend(frontendName, equipmentName); - front->FeMain(argc, argv); -} - ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, const char *equipmentFileName) : TMFeEquipment(equipmentName.c_str(), equipmentFileName), @@ -203,9 +163,3 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->numberOfOutlet = epicsOutletNumber; } - -ePowerSwitchFrontend::ePowerSwitchFrontend(std::string frontendName, - std::string equipmentName) { - FeSetName(frontendName.c_str()); - FeAddEquipment(new ePowerSwitchEquipment(equipmentName.c_str(), __FILE__)); -} \ No newline at end of file diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h new file mode 100644 index 0000000..651732f --- /dev/null +++ b/src/device/ePowerSwitchEquipment.h @@ -0,0 +1,49 @@ +#ifndef EPOWERSWITCH_EQUIPMENT_H +#define EPOWERSWITCH_EQUIPMENT_H + +#include "m_epics_ca.h" +#include "tmfe.h" +#include + +class ePowerSwitchEquipment : public TMFeEquipment { + + public: + /** + * @brief constructor + * + * @param equipmentName name show on Midas for the equipment + * @param equipmentFileName file name for automatically tagged message + */ + ePowerSwitchEquipment(std::string equipmentName, + const char *equipmentFileName); + + /** + * @brief called periodically by Midas + */ + void HandlePeriodic(); + + private: + std::vector *> outletSetRecords; + std::vector *> outletGetRecords; + mEpicsCa outletNumberRecord; + int numberOfOutlet; + + /** + * @brief refresh information about the given socket ID + * + * @param socketId which socket to refresh + */ + void refreshSocket(int socketId); + + /** + * @brief refresh information about all the available sockets + */ + void refreshAllSockets(); + + /** + * @brief detect and modify the current socket pool in case of change + */ + void updateSocketNumber(); +}; + +#endif \ No newline at end of file diff --git a/include/ePowerSwitchConfig.h b/src/device/ePowerSwitchEquipmentConfig.h similarity index 75% rename from include/ePowerSwitchConfig.h rename to src/device/ePowerSwitchEquipmentConfig.h index 933e254..e0a407e 100644 --- a/include/ePowerSwitchConfig.h +++ b/src/device/ePowerSwitchEquipmentConfig.h @@ -5,7 +5,4 @@ #define EPOWERSWITCH_SOCKET_GET_PREFIX "ePowerSwitch_get_outlet_" #define EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX "ePowerSwitch_config_maxOutlet" -#define DEFAULT_FRONTEND_NAME "ePowerSwitch" -#define DEFAULT_EQUIPMENT_NAME "powerswitch" - #endif diff --git a/src/frontend/ePowerSwitchFrontend.cpp b/src/frontend/ePowerSwitchFrontend.cpp new file mode 100644 index 0000000..56ec3f8 --- /dev/null +++ b/src/frontend/ePowerSwitchFrontend.cpp @@ -0,0 +1,49 @@ +#include "ePowerSwitchFrontend.h" +#include "../device/ePowerSwitchEquipment.h" +#include "ePowerSwitchFrontendConfig.h" +#include "tmfe.h" + +int main(int argc, char *argv[]) { + + if (argv[0][0] == '.') { + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Relative paths are strongly discouraged; " + "please use an absolute path."); + } + + std::string frontendName; + std::string equipmentName; + + if (argc == 1) { + frontendName = DEFAULT_FRONTEND_NAME; + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "No frontend name provided; %s will be used", + DEFAULT_FRONTEND_NAME); + equipmentName = DEFAULT_EQUIPMENT_NAME; + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "No equipment name provided; %s will be used", + DEFAULT_EQUIPMENT_NAME); + } + if (argc == 2) { + frontendName = std::string(argv[1]); + argv++; + argc--; + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "No equipment name provided; %s will be use", + DEFAULT_EQUIPMENT_NAME); + } else if (argc == 3) { + frontendName = std::string(argv[1]); + equipmentName = std::string(argv[2]); + argv += 2; + argc -= 2; + } + + auto front = new ePowerSwitchFrontend(frontendName, equipmentName); + front->FeMain(argc, argv); +} + +ePowerSwitchFrontend::ePowerSwitchFrontend(std::string frontendName, + std::string equipmentName) { + FeSetName(frontendName.c_str()); + FeAddEquipment(new ePowerSwitchEquipment(equipmentName.c_str(), __FILE__)); +} \ No newline at end of file diff --git a/src/frontend/ePowerSwitchFrontend.h b/src/frontend/ePowerSwitchFrontend.h new file mode 100644 index 0000000..7649d92 --- /dev/null +++ b/src/frontend/ePowerSwitchFrontend.h @@ -0,0 +1,17 @@ +#ifndef EPOWERSWITCH_FRONTEND_H +#define EPOWERSWITCH_FRONTEND_H + +#include "tmfe.h" + +class ePowerSwitchFrontend : public TMFrontend { + public: + /** + * @brief constructor + * + * @param frontendName name shown on Midas for the frontend + * @param equipmentName name shown on Midas for the equipment + */ + ePowerSwitchFrontend(std::string frontendName, std::string equipmentName); +}; + +#endif \ No newline at end of file diff --git a/src/frontend/ePowerSwitchFrontendConfig.h b/src/frontend/ePowerSwitchFrontendConfig.h new file mode 100644 index 0000000..8df2e9b --- /dev/null +++ b/src/frontend/ePowerSwitchFrontendConfig.h @@ -0,0 +1,7 @@ +#ifndef EPOWERSWITCH_CONFIG_H +#define EPOWERSWITCH_CONFIG_H + +#define DEFAULT_FRONTEND_NAME "ePowerSwitch" +#define DEFAULT_EQUIPMENT_NAME "powerswitch" + +#endif \ No newline at end of file -- 2.52.0 From 61617a60dad2fff7906f11f0337f84c5b67a5ef6 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Apr 2026 16:00:25 +0200 Subject: [PATCH 02/22] switching to newer mepicsca --- submodule/mepicsca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodule/mepicsca b/submodule/mepicsca index abc5781..419df88 160000 --- a/submodule/mepicsca +++ b/submodule/mepicsca @@ -1 +1 @@ -Subproject commit abc57815eb9992d489d30fd315f93ded52ebc5a0 +Subproject commit 419df88dde85d8dc3150c7632c4214950b92c881 -- 2.52.0 From d228b193fdf354022ca544ea527f168a0ae42ad7 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Apr 2026 16:29:08 +0200 Subject: [PATCH 03/22] bug --- src/device/ePowerSwitchEquipment.cpp | 25 +++++++++++-------------- src/device/ePowerSwitchEquipment.h | 4 ++-- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 42ff785..889a617 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -57,7 +57,7 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { std::string epicsCurrentSocketState; mepicscaReturnCode = - this->outletGetRecords.at(socketId)->get(&epicsCurrentSocketState); + this->outletGetRecords.at(socketId).get(&epicsCurrentSocketState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, @@ -68,8 +68,8 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { } if (epicsCurrentSocketState != midasRequestedSocketState) { - mepicscaReturnCode = this->outletSetRecords.at(socketId)->put( - &midasRequestedSocketState); + mepicscaReturnCode = + this->outletSetRecords.at(socketId).put(&midasRequestedSocketState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, @@ -122,13 +122,15 @@ void ePowerSwitchEquipment::updateSocketNumber() { std::string epicsSetRecordName = format(EPOWERSWITCH_SOCKET_SET_PREFIX, i); - this->outletSetRecords.push_back( - new mEpicsCa(epicsSetRecordName.c_str())); + mEpicsCa record = + mEpicsCa(epicsSetRecordName.c_str()); + + this->outletSetRecords.push_back(record); std::string epicsGetRecordName = format(EPOWERSWITCH_SOCKET_GET_PREFIX, i); - this->outletGetRecords.push_back( - new mEpicsCa(epicsGetRecordName.c_str())); + // this->outletGetRecords.push_back(); + // mEpicsCa(epicsGetRecordName.c_str())); } if (this->numberOfOutlet > epicsOutletNumber) @@ -137,10 +139,8 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->numberOfOutlet - epicsOutletNumber); for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { - mEpicsCa *setRecord = this->outletSetRecords.back(); - delete setRecord; - mEpicsCa *getRecord = this->outletGetRecords.back(); - delete getRecord; + this->outletSetRecords.pop_back(); + this->outletGetRecords.pop_back(); std::string requestedVarname = format("Socket ", i) + std::string(" requested"); @@ -156,9 +156,6 @@ void ePowerSwitchEquipment::updateSocketNumber() { fOdbEqVariables->Delete(currentVarname.c_str(), &ovbError); if (ovbError.fError) fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - - this->outletSetRecords.pop_back(); - this->outletGetRecords.pop_back(); } this->numberOfOutlet = epicsOutletNumber; diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h index 651732f..4fc1297 100644 --- a/src/device/ePowerSwitchEquipment.h +++ b/src/device/ePowerSwitchEquipment.h @@ -23,8 +23,8 @@ class ePowerSwitchEquipment : public TMFeEquipment { void HandlePeriodic(); private: - std::vector *> outletSetRecords; - std::vector *> outletGetRecords; + std::vector> outletSetRecords; + std::vector> outletGetRecords; mEpicsCa outletNumberRecord; int numberOfOutlet; -- 2.52.0 From bdefd57cf66cc8bcdca06f61b84dc0525f4cc92b Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Apr 2026 16:42:45 +0200 Subject: [PATCH 04/22] Revert "switching to newer mepicsca" This reverts commit 61617a60dad2fff7906f11f0337f84c5b67a5ef6. --- submodule/mepicsca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodule/mepicsca b/submodule/mepicsca index 419df88..abc5781 160000 --- a/submodule/mepicsca +++ b/submodule/mepicsca @@ -1 +1 @@ -Subproject commit 419df88dde85d8dc3150c7632c4214950b92c881 +Subproject commit abc57815eb9992d489d30fd315f93ded52ebc5a0 -- 2.52.0 From 6c63de1d842f29148fc1990ebafe3d186ea722f2 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Apr 2026 16:43:25 +0200 Subject: [PATCH 05/22] Revert "bug" This reverts commit d228b193fdf354022ca544ea527f168a0ae42ad7. --- src/device/ePowerSwitchEquipment.cpp | 25 ++++++++++++++----------- src/device/ePowerSwitchEquipment.h | 4 ++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 889a617..42ff785 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -57,7 +57,7 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { std::string epicsCurrentSocketState; mepicscaReturnCode = - this->outletGetRecords.at(socketId).get(&epicsCurrentSocketState); + this->outletGetRecords.at(socketId)->get(&epicsCurrentSocketState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, @@ -68,8 +68,8 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { } if (epicsCurrentSocketState != midasRequestedSocketState) { - mepicscaReturnCode = - this->outletSetRecords.at(socketId).put(&midasRequestedSocketState); + mepicscaReturnCode = this->outletSetRecords.at(socketId)->put( + &midasRequestedSocketState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, @@ -122,15 +122,13 @@ void ePowerSwitchEquipment::updateSocketNumber() { std::string epicsSetRecordName = format(EPOWERSWITCH_SOCKET_SET_PREFIX, i); - mEpicsCa record = - mEpicsCa(epicsSetRecordName.c_str()); - - this->outletSetRecords.push_back(record); + this->outletSetRecords.push_back( + new mEpicsCa(epicsSetRecordName.c_str())); std::string epicsGetRecordName = format(EPOWERSWITCH_SOCKET_GET_PREFIX, i); - // this->outletGetRecords.push_back(); - // mEpicsCa(epicsGetRecordName.c_str())); + this->outletGetRecords.push_back( + new mEpicsCa(epicsGetRecordName.c_str())); } if (this->numberOfOutlet > epicsOutletNumber) @@ -139,8 +137,10 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->numberOfOutlet - epicsOutletNumber); for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { - this->outletSetRecords.pop_back(); - this->outletGetRecords.pop_back(); + mEpicsCa *setRecord = this->outletSetRecords.back(); + delete setRecord; + mEpicsCa *getRecord = this->outletGetRecords.back(); + delete getRecord; std::string requestedVarname = format("Socket ", i) + std::string(" requested"); @@ -156,6 +156,9 @@ void ePowerSwitchEquipment::updateSocketNumber() { fOdbEqVariables->Delete(currentVarname.c_str(), &ovbError); if (ovbError.fError) fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + + this->outletSetRecords.pop_back(); + this->outletGetRecords.pop_back(); } this->numberOfOutlet = epicsOutletNumber; diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h index 4fc1297..651732f 100644 --- a/src/device/ePowerSwitchEquipment.h +++ b/src/device/ePowerSwitchEquipment.h @@ -23,8 +23,8 @@ class ePowerSwitchEquipment : public TMFeEquipment { void HandlePeriodic(); private: - std::vector> outletSetRecords; - std::vector> outletGetRecords; + std::vector *> outletSetRecords; + std::vector *> outletGetRecords; mEpicsCa outletNumberRecord; int numberOfOutlet; -- 2.52.0 From 616f1cbf78650a61592b2b3c870753211e2dd697 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Thu, 30 Apr 2026 16:54:34 +0200 Subject: [PATCH 06/22] adding new version of mepicsca and using unique ptr --- src/device/ePowerSwitchEquipment.cpp | 10 ++++------ src/device/ePowerSwitchEquipment.h | 4 ++-- submodule/mepicsca | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 42ff785..dbd29ea 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -123,12 +123,14 @@ void ePowerSwitchEquipment::updateSocketNumber() { format(EPOWERSWITCH_SOCKET_SET_PREFIX, i); this->outletSetRecords.push_back( - new mEpicsCa(epicsSetRecordName.c_str())); + std::make_unique>( + epicsSetRecordName.c_str())); std::string epicsGetRecordName = format(EPOWERSWITCH_SOCKET_GET_PREFIX, i); this->outletGetRecords.push_back( - new mEpicsCa(epicsGetRecordName.c_str())); + std::make_unique>( + epicsGetRecordName.c_str())); } if (this->numberOfOutlet > epicsOutletNumber) @@ -137,10 +139,6 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->numberOfOutlet - epicsOutletNumber); for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { - mEpicsCa *setRecord = this->outletSetRecords.back(); - delete setRecord; - mEpicsCa *getRecord = this->outletGetRecords.back(); - delete getRecord; std::string requestedVarname = format("Socket ", i) + std::string(" requested"); diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h index 651732f..751a4ef 100644 --- a/src/device/ePowerSwitchEquipment.h +++ b/src/device/ePowerSwitchEquipment.h @@ -23,8 +23,8 @@ class ePowerSwitchEquipment : public TMFeEquipment { void HandlePeriodic(); private: - std::vector *> outletSetRecords; - std::vector *> outletGetRecords; + std::vector>> outletSetRecords; + std::vector>> outletGetRecords; mEpicsCa outletNumberRecord; int numberOfOutlet; diff --git a/submodule/mepicsca b/submodule/mepicsca index abc5781..419df88 160000 --- a/submodule/mepicsca +++ b/submodule/mepicsca @@ -1 +1 @@ -Subproject commit abc57815eb9992d489d30fd315f93ded52ebc5a0 +Subproject commit 419df88dde85d8dc3150c7632c4214950b92c881 -- 2.52.0 From 739888925a9e2d694b08a26c40283a4210074bf7 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 08:40:05 +0200 Subject: [PATCH 07/22] removing new --- src/frontend/ePowerSwitchFrontend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/ePowerSwitchFrontend.cpp b/src/frontend/ePowerSwitchFrontend.cpp index 56ec3f8..29b06a9 100644 --- a/src/frontend/ePowerSwitchFrontend.cpp +++ b/src/frontend/ePowerSwitchFrontend.cpp @@ -38,8 +38,8 @@ int main(int argc, char *argv[]) { argc -= 2; } - auto front = new ePowerSwitchFrontend(frontendName, equipmentName); - front->FeMain(argc, argv); + auto front = ePowerSwitchFrontend(frontendName, equipmentName); + front.FeMain(argc, argv); } ePowerSwitchFrontend::ePowerSwitchFrontend(std::string frontendName, -- 2.52.0 From 5ec5df0a56c704b9c9d78b60cff62f81ee9ab773 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 08:41:26 +0200 Subject: [PATCH 08/22] default equipment name and frontend name assigne, and overwiten if necessary --- src/frontend/ePowerSwitchFrontend.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/frontend/ePowerSwitchFrontend.cpp b/src/frontend/ePowerSwitchFrontend.cpp index 29b06a9..1e56e18 100644 --- a/src/frontend/ePowerSwitchFrontend.cpp +++ b/src/frontend/ePowerSwitchFrontend.cpp @@ -11,15 +11,13 @@ int main(int argc, char *argv[]) { "please use an absolute path."); } - std::string frontendName; - std::string equipmentName; + std::string frontendName = DEFAULT_FRONTEND_NAME; + std::string equipmentName = DEFAULT_EQUIPMENT_NAME; if (argc == 1) { - frontendName = DEFAULT_FRONTEND_NAME; TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No frontend name provided; %s will be used", DEFAULT_FRONTEND_NAME); - equipmentName = DEFAULT_EQUIPMENT_NAME; TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No equipment name provided; %s will be used", DEFAULT_EQUIPMENT_NAME); -- 2.52.0 From 95cb1ea2466b4dbc9d8c0be737cf2e8073d99841 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 10:51:33 +0200 Subject: [PATCH 09/22] exposing socket name in settings --- CMakeLists.txt | 2 +- src/device/ePowerSwitchEquipment.cpp | 37 ++++++++++++++++++++++++ src/device/ePowerSwitchEquipment.h | 6 ++++ src/device/ePowerSwitchEquipmentConfig.h | 3 ++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb5ecd8..70ce644 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ target_include_directories( target_link_libraries( ePowerSwitchFrontend PRIVATE - ePowerSwitchEquipment + ePowerSwitchEquipment midas::mfe m_epics_ca ${LIBS} diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index dbd29ea..2c408a2 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -16,6 +16,15 @@ std::string format(std::string str, int value) { return ss.str(); } +std::string getDefaultSocketName(int socketId) { + std::string res = std::string(EPOWERSWITCH_DEFAULT_SOCKET_NAME) + .append(std::to_string(socketId)); + + printf("get default %s\n", res.c_str()); + + return res; +} + ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, const char *equipmentFileName) : TMFeEquipment(equipmentName.c_str(), equipmentFileName), @@ -35,9 +44,11 @@ ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, void ePowerSwitchEquipment::HandlePeriodic() { updateSocketNumber(); refreshAllSockets(); + updateSocketNames(); } void ePowerSwitchEquipment::refreshSocket(int socketId) { + std::string requestedVarname = format("Socket ", socketId) + std::string(" requested"); std::string currentVarname = @@ -131,6 +142,8 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->outletGetRecords.push_back( std::make_unique>( epicsGetRecordName.c_str())); + + this->socketNames.push_back(getDefaultSocketName(i)); } if (this->numberOfOutlet > epicsOutletNumber) @@ -157,7 +170,31 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->outletSetRecords.pop_back(); this->outletGetRecords.pop_back(); + this->socketNames.pop_back(); } this->numberOfOutlet = epicsOutletNumber; } + +void ePowerSwitchEquipment::updateSocketNames() { + std::string varname = EPOWERSWITCH_SOCKET_NAME_SETTINGS; + varname.reserve(varname.length() + 1); + + MVOdbError ovbError; + + for (int i = 0; i < this->numberOfOutlet; i++) { + std::string socketName = getDefaultSocketName(i); + varname[7] = '0' + i; + fOdbEqSettings->RS(varname.c_str(), &socketName, true, + socketName.length() + 1, &ovbError); + if (ovbError.fError) + fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + + printf("%s as the name %s\n", varname.c_str(), socketName.c_str()); + + if (this->socketNames.at(i) != socketName) { + printf("new name %s\n", socketName.c_str()); + this->socketNames.at(i) = socketName; + } + } +} diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h index 751a4ef..a3c65f3 100644 --- a/src/device/ePowerSwitchEquipment.h +++ b/src/device/ePowerSwitchEquipment.h @@ -25,6 +25,7 @@ class ePowerSwitchEquipment : public TMFeEquipment { private: std::vector>> outletSetRecords; std::vector>> outletGetRecords; + std::vector socketNames; mEpicsCa outletNumberRecord; int numberOfOutlet; @@ -44,6 +45,11 @@ class ePowerSwitchEquipment : public TMFeEquipment { * @brief detect and modify the current socket pool in case of change */ void updateSocketNumber(); + + /** + * @brief update socketNames by reading settings ODB + */ + void updateSocketNames(); }; #endif \ No newline at end of file diff --git a/src/device/ePowerSwitchEquipmentConfig.h b/src/device/ePowerSwitchEquipmentConfig.h index e0a407e..1ab55ee 100644 --- a/src/device/ePowerSwitchEquipmentConfig.h +++ b/src/device/ePowerSwitchEquipmentConfig.h @@ -5,4 +5,7 @@ #define EPOWERSWITCH_SOCKET_GET_PREFIX "ePowerSwitch_get_outlet_" #define EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX "ePowerSwitch_config_maxOutlet" +#define EPOWERSWITCH_DEFAULT_SOCKET_NAME "Socket " +#define EPOWERSWITCH_SOCKET_NAME_SETTINGS "Socket n name" + #endif -- 2.52.0 From 9270476caecfb6a385c62b708aa5818fa8be426d Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 11:11:55 +0200 Subject: [PATCH 10/22] Revert "default equipment name and frontend name assigne, and overwiten if necessary" This reverts commit 5ec5df0a56c704b9c9d78b60cff62f81ee9ab773. --- src/frontend/ePowerSwitchFrontend.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/frontend/ePowerSwitchFrontend.cpp b/src/frontend/ePowerSwitchFrontend.cpp index 1e56e18..29b06a9 100644 --- a/src/frontend/ePowerSwitchFrontend.cpp +++ b/src/frontend/ePowerSwitchFrontend.cpp @@ -11,13 +11,15 @@ int main(int argc, char *argv[]) { "please use an absolute path."); } - std::string frontendName = DEFAULT_FRONTEND_NAME; - std::string equipmentName = DEFAULT_EQUIPMENT_NAME; + std::string frontendName; + std::string equipmentName; if (argc == 1) { + frontendName = DEFAULT_FRONTEND_NAME; TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No frontend name provided; %s will be used", DEFAULT_FRONTEND_NAME); + equipmentName = DEFAULT_EQUIPMENT_NAME; TMFE::Instance()->Msg(MINFO, __FUNCTION__, "No equipment name provided; %s will be used", DEFAULT_EQUIPMENT_NAME); -- 2.52.0 From b1b131b525b1dd75a2e6457e474d317e43d4021e Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 14:25:47 +0200 Subject: [PATCH 11/22] adding a new field to outlet name --- src/device/ePowerSwitchEquipment.cpp | 138 ++++++++++++----------- src/device/ePowerSwitchEquipment.h | 5 - src/device/ePowerSwitchEquipmentConfig.h | 12 +- 3 files changed, 82 insertions(+), 73 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 2c408a2..3417036 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -4,25 +4,16 @@ #include /** - * @brief local function: append an integer to the end of a string. - * @param str string prefix - * @param value integer to append - * @return "str" + integer + * @brief Insert a integer value between two string + * @param str1 first string + * @param int value to insert + * @param str2 second string + * + * @return a new string instance */ -std::string format(std::string str, int value) { - std::stringstream ss; - ss << str; - ss << value; - return ss.str(); -} - -std::string getDefaultSocketName(int socketId) { - std::string res = std::string(EPOWERSWITCH_DEFAULT_SOCKET_NAME) - .append(std::to_string(socketId)); - - printf("get default %s\n", res.c_str()); - - return res; +std::string insert(const std::string *str1, int value, + const std::string *str2) { + return *str1 + std::to_string(value) + *str2; } ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, @@ -31,12 +22,11 @@ ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, outletNumberRecord(mEpicsCa( std::string_view(EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX))) { - fEqConfReadConfigFromOdb = false; /// i don't know what this parameter does - fEqConfPeriodMilliSec = 1000; /// refresh rate of midas frontend + fEqConfPeriodMilliSec = 1000; // refresh rate of midas frontend fEqConfLogHistory = - 60; /// enable history system, generate one event per minutes - fEqConfReadOnlyWhenRunning = false; /// allow to write values when running - fEqConfWriteEventsToOdb = true; /// i don't know + 60; // enable history system, generate one event per minutes + fEqConfReadOnlyWhenRunning = false; // allow to write values when running + fEqConfWriteEventsToOdb = true; // allow to write event to the odb this->numberOfOutlet = 0; } @@ -44,19 +34,44 @@ ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, void ePowerSwitchEquipment::HandlePeriodic() { updateSocketNumber(); refreshAllSockets(); - updateSocketNames(); } void ePowerSwitchEquipment::refreshSocket(int socketId) { - std::string requestedVarname = - format("Socket ", socketId) + std::string(" requested"); - std::string currentVarname = - format("Socket ", socketId) + std::string(" current"); - + std::string usernameVarname; + { + static const std::string str1 = "Socket "; + static const std::string str2 = " name"; + usernameVarname = insert(&str1, socketId, &str2); + } + std::string requestedVarname; + { + static const std::string str1 = "|-> "; + static const std::string str2 = " requested"; + requestedVarname = insert(&str1, socketId, &str2); + } + std::string currentVarname; + { + static const std::string str1 = "\\-> "; + static const std::string str2 = " current"; + currentVarname = insert(&str1, socketId, &str2); + } + std::string midasUsername; + { + static const std::string str1 = "Socket "; + static const std::string str2 = ""; + midasUsername = insert(&str1, socketId, &str2); + } std::string midasRequestedSocketState = std::string("Off"); MVOdbError ovbError; int mepicscaReturnCode; + fOdbEqVariables->RS(usernameVarname.c_str(), &midasUsername, true, + midasUsername.length() + 1, &ovbError); + if (ovbError.fError) { + fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + exit(EXIT_FAILURE); + } + fOdbEqVariables->RS(requestedVarname.c_str(), &midasRequestedSocketState, true, midasRequestedSocketState.length() + 1, &ovbError); @@ -66,6 +81,15 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { exit(EXIT_FAILURE); } + std::string defaultCurrentState = "unknow"; + fOdbEqVariables->RS(currentVarname.c_str(), &defaultCurrentState, true, + defaultCurrentState.length() + 1, &ovbError); + + if (ovbError.fError) { + fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + exit(EXIT_FAILURE); + } + std::string epicsCurrentSocketState; mepicscaReturnCode = this->outletGetRecords.at(socketId)->get(&epicsCurrentSocketState); @@ -130,20 +154,27 @@ void ePowerSwitchEquipment::updateSocketNumber() { epicsOutletNumber - this->numberOfOutlet); for (int i = this->numberOfOutlet; i < epicsOutletNumber; i++) { - std::string epicsSetRecordName = - format(EPOWERSWITCH_SOCKET_SET_PREFIX, i); + std::string epicsSetRecordName; + { + static const std::string *str1 = &EPOWERSWITCH_SOCKET_SET_PREFIX; + static const std::string str2 = ""; + epicsSetRecordName = insert(str1, i, &str2); + } this->outletSetRecords.push_back( std::make_unique>( epicsSetRecordName.c_str())); - std::string epicsGetRecordName = - format(EPOWERSWITCH_SOCKET_GET_PREFIX, i); + std::string epicsGetRecordName; + { + static const std::string *str1 = &EPOWERSWITCH_SOCKET_GET_PREFIX; + static const std::string str2 = ""; + epicsGetRecordName = insert(str1, i, &str2); + } + this->outletGetRecords.push_back( std::make_unique>( epicsGetRecordName.c_str())); - - this->socketNames.push_back(getDefaultSocketName(i)); } if (this->numberOfOutlet > epicsOutletNumber) @@ -153,10 +184,15 @@ void ePowerSwitchEquipment::updateSocketNumber() { for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { - std::string requestedVarname = - format("Socket ", i) + std::string(" requested"); - std::string currentVarname = - format("Socket ", i) + std::string(" current"); + std::string requestedVarname; + std::string currentVarname; + { + static const std::string str1 = "Socket "; + static const std::string str2a = " current"; + static const std::string str2b = " requested"; + requestedVarname = insert(&str1, i, &str2a); + currentVarname = insert(&str1, i, &str2b); + } MVOdbError ovbError; @@ -170,31 +206,7 @@ void ePowerSwitchEquipment::updateSocketNumber() { this->outletSetRecords.pop_back(); this->outletGetRecords.pop_back(); - this->socketNames.pop_back(); } this->numberOfOutlet = epicsOutletNumber; } - -void ePowerSwitchEquipment::updateSocketNames() { - std::string varname = EPOWERSWITCH_SOCKET_NAME_SETTINGS; - varname.reserve(varname.length() + 1); - - MVOdbError ovbError; - - for (int i = 0; i < this->numberOfOutlet; i++) { - std::string socketName = getDefaultSocketName(i); - varname[7] = '0' + i; - fOdbEqSettings->RS(varname.c_str(), &socketName, true, - socketName.length() + 1, &ovbError); - if (ovbError.fError) - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - - printf("%s as the name %s\n", varname.c_str(), socketName.c_str()); - - if (this->socketNames.at(i) != socketName) { - printf("new name %s\n", socketName.c_str()); - this->socketNames.at(i) = socketName; - } - } -} diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h index a3c65f3..4ac8032 100644 --- a/src/device/ePowerSwitchEquipment.h +++ b/src/device/ePowerSwitchEquipment.h @@ -45,11 +45,6 @@ class ePowerSwitchEquipment : public TMFeEquipment { * @brief detect and modify the current socket pool in case of change */ void updateSocketNumber(); - - /** - * @brief update socketNames by reading settings ODB - */ - void updateSocketNames(); }; #endif \ No newline at end of file diff --git a/src/device/ePowerSwitchEquipmentConfig.h b/src/device/ePowerSwitchEquipmentConfig.h index 1ab55ee..663e6e1 100644 --- a/src/device/ePowerSwitchEquipmentConfig.h +++ b/src/device/ePowerSwitchEquipmentConfig.h @@ -1,11 +1,13 @@ #ifndef EPOWERSWITCH_CONFIG_H #define EPOWERSWITCH_CONFIG_H +#include -#define EPOWERSWITCH_SOCKET_SET_PREFIX "ePowerSwitch_set_outlet_" -#define EPOWERSWITCH_SOCKET_GET_PREFIX "ePowerSwitch_get_outlet_" -#define EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX "ePowerSwitch_config_maxOutlet" +const std::string EPOWERSWITCH_SOCKET_SET_PREFIX = "ePowerSwitch_set_outlet_"; +const std::string EPOWERSWITCH_SOCKET_GET_PREFIX = "ePowerSwitch_get_outlet_"; +const std::string EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX = + "ePowerSwitch_config_maxOutlet"; -#define EPOWERSWITCH_DEFAULT_SOCKET_NAME "Socket " -#define EPOWERSWITCH_SOCKET_NAME_SETTINGS "Socket n name" +const std::string EPOWERSWITCH_DEFAULT_SOCKET_NAME = "Socket"; +const std::string EPOWERSWITCH_DEFAULT_SOCKET_STATUS = "Off"; #endif -- 2.52.0 From 34cc107eb537429bcf84af5837278b765cfb1e5f Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 14:32:01 +0200 Subject: [PATCH 12/22] renaming socket to outlet --- src/device/ePowerSwitchEquipment.cpp | 64 ++++++++++++------------ src/device/ePowerSwitchEquipment.h | 16 +++--- src/device/ePowerSwitchEquipmentConfig.h | 10 ++-- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 3417036..cd6fc4c 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -20,7 +20,7 @@ ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, const char *equipmentFileName) : TMFeEquipment(equipmentName.c_str(), equipmentFileName), outletNumberRecord(mEpicsCa( - std::string_view(EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX))) { + std::string_view(EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX))) { fEqConfPeriodMilliSec = 1000; // refresh rate of midas frontend fEqConfLogHistory = @@ -32,37 +32,37 @@ ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, } void ePowerSwitchEquipment::HandlePeriodic() { - updateSocketNumber(); - refreshAllSockets(); + updateOutletNumber(); + refreshAllOutlets(); } -void ePowerSwitchEquipment::refreshSocket(int socketId) { +void ePowerSwitchEquipment::refreshOutlet(int outletId) { std::string usernameVarname; { - static const std::string str1 = "Socket "; + static const std::string str1 = "Outlet "; static const std::string str2 = " name"; - usernameVarname = insert(&str1, socketId, &str2); + usernameVarname = insert(&str1, outletId, &str2); } std::string requestedVarname; { static const std::string str1 = "|-> "; static const std::string str2 = " requested"; - requestedVarname = insert(&str1, socketId, &str2); + requestedVarname = insert(&str1, outletId, &str2); } std::string currentVarname; { static const std::string str1 = "\\-> "; static const std::string str2 = " current"; - currentVarname = insert(&str1, socketId, &str2); + currentVarname = insert(&str1, outletId, &str2); } std::string midasUsername; { - static const std::string str1 = "Socket "; + static const std::string str1 = "Outlet "; static const std::string str2 = ""; - midasUsername = insert(&str1, socketId, &str2); + midasUsername = insert(&str1, outletId, &str2); } - std::string midasRequestedSocketState = std::string("Off"); + std::string midasRequestedOutletState = std::string("Off"); MVOdbError ovbError; int mepicscaReturnCode; fOdbEqVariables->RS(usernameVarname.c_str(), &midasUsername, true, @@ -72,8 +72,8 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { exit(EXIT_FAILURE); } - fOdbEqVariables->RS(requestedVarname.c_str(), &midasRequestedSocketState, - true, midasRequestedSocketState.length() + 1, + fOdbEqVariables->RS(requestedVarname.c_str(), &midasRequestedOutletState, + true, midasRequestedOutletState.length() + 1, &ovbError); if (ovbError.fError) { @@ -90,33 +90,33 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { exit(EXIT_FAILURE); } - std::string epicsCurrentSocketState; + std::string epicsCurrentOutletState; mepicscaReturnCode = - this->outletGetRecords.at(socketId)->get(&epicsCurrentSocketState); + this->outletGetRecords.at(outletId)->get(&epicsCurrentOutletState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, - "Couldn't get the value, skipping refreshing socket %d. " + "Couldn't get the value, skipping refreshing outlet %d. " "Error code %d", - socketId, mepicscaReturnCode); + outletId, mepicscaReturnCode); return; } - if (epicsCurrentSocketState != midasRequestedSocketState) { - mepicscaReturnCode = this->outletSetRecords.at(socketId)->put( - &midasRequestedSocketState); + if (epicsCurrentOutletState != midasRequestedOutletState) { + mepicscaReturnCode = this->outletSetRecords.at(outletId)->put( + &midasRequestedOutletState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, - "Couldn't put the value, skipping refreshing socket %d. " + "Couldn't put the value, skipping refreshing outlet %d. " "Error code %d", - socketId, mepicscaReturnCode); + outletId, mepicscaReturnCode); return; } } - fOdbEqVariables->WS(currentVarname.c_str(), epicsCurrentSocketState.c_str(), - epicsCurrentSocketState.length() + 1, &ovbError); + fOdbEqVariables->WS(currentVarname.c_str(), epicsCurrentOutletState.c_str(), + epicsCurrentOutletState.length() + 1, &ovbError); if (ovbError.fError) { fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); @@ -124,13 +124,13 @@ void ePowerSwitchEquipment::refreshSocket(int socketId) { } } -void ePowerSwitchEquipment::refreshAllSockets() { +void ePowerSwitchEquipment::refreshAllOutlets() { for (int i = 0; i < this->numberOfOutlet; i++) { - refreshSocket(i); + refreshOutlet(i); } } -void ePowerSwitchEquipment::updateSocketNumber() { +void ePowerSwitchEquipment::updateOutletNumber() { int epicsOutletNumber = 0; if (!outletNumberRecord.connected()) { @@ -150,13 +150,13 @@ void ePowerSwitchEquipment::updateSocketNumber() { if (this->numberOfOutlet < epicsOutletNumber) fMfe->Msg(MDEBUG, __FUNCTION__, - "Socket number increasing, creating %d new socket(s)", + "Outlet number increasing, creating %d new outlet(s)", epicsOutletNumber - this->numberOfOutlet); for (int i = this->numberOfOutlet; i < epicsOutletNumber; i++) { std::string epicsSetRecordName; { - static const std::string *str1 = &EPOWERSWITCH_SOCKET_SET_PREFIX; + static const std::string *str1 = &EPOWERSWITCH_OUTLET_SET_PREFIX; static const std::string str2 = ""; epicsSetRecordName = insert(str1, i, &str2); } @@ -167,7 +167,7 @@ void ePowerSwitchEquipment::updateSocketNumber() { std::string epicsGetRecordName; { - static const std::string *str1 = &EPOWERSWITCH_SOCKET_GET_PREFIX; + static const std::string *str1 = &EPOWERSWITCH_OUTLET_GET_PREFIX; static const std::string str2 = ""; epicsGetRecordName = insert(str1, i, &str2); } @@ -179,7 +179,7 @@ void ePowerSwitchEquipment::updateSocketNumber() { if (this->numberOfOutlet > epicsOutletNumber) fMfe->Msg(MDEBUG, __FUNCTION__, - "Socket number decreasing, destroying %d socket(s)", + "Outlet number decreasing, destroying %d outlet(s)", this->numberOfOutlet - epicsOutletNumber); for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { @@ -187,7 +187,7 @@ void ePowerSwitchEquipment::updateSocketNumber() { std::string requestedVarname; std::string currentVarname; { - static const std::string str1 = "Socket "; + static const std::string str1 = "Outlet "; static const std::string str2a = " current"; static const std::string str2b = " requested"; requestedVarname = insert(&str1, i, &str2a); diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h index 4ac8032..e514de2 100644 --- a/src/device/ePowerSwitchEquipment.h +++ b/src/device/ePowerSwitchEquipment.h @@ -25,26 +25,26 @@ class ePowerSwitchEquipment : public TMFeEquipment { private: std::vector>> outletSetRecords; std::vector>> outletGetRecords; - std::vector socketNames; + std::vector outletNames; mEpicsCa outletNumberRecord; int numberOfOutlet; /** - * @brief refresh information about the given socket ID + * @brief refresh information about the given outlet ID * - * @param socketId which socket to refresh + * @param outletId which outlet to refresh */ - void refreshSocket(int socketId); + void refreshOutlet(int outletId); /** - * @brief refresh information about all the available sockets + * @brief refresh information about all the available outlets */ - void refreshAllSockets(); + void refreshAllOutlets(); /** - * @brief detect and modify the current socket pool in case of change + * @brief detect and modify the current outlet pool in case of change */ - void updateSocketNumber(); + void updateOutletNumber(); }; #endif \ No newline at end of file diff --git a/src/device/ePowerSwitchEquipmentConfig.h b/src/device/ePowerSwitchEquipmentConfig.h index 663e6e1..e4e83f1 100644 --- a/src/device/ePowerSwitchEquipmentConfig.h +++ b/src/device/ePowerSwitchEquipmentConfig.h @@ -2,12 +2,12 @@ #define EPOWERSWITCH_CONFIG_H #include -const std::string EPOWERSWITCH_SOCKET_SET_PREFIX = "ePowerSwitch_set_outlet_"; -const std::string EPOWERSWITCH_SOCKET_GET_PREFIX = "ePowerSwitch_get_outlet_"; -const std::string EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX = +const std::string EPOWERSWITCH_OUTLET_SET_PREFIX = "ePowerSwitch_set_outlet_"; +const std::string EPOWERSWITCH_OUTLET_GET_PREFIX = "ePowerSwitch_get_outlet_"; +const std::string EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX = "ePowerSwitch_config_maxOutlet"; -const std::string EPOWERSWITCH_DEFAULT_SOCKET_NAME = "Socket"; -const std::string EPOWERSWITCH_DEFAULT_SOCKET_STATUS = "Off"; +const std::string EPOWERSWITCH_DEFAULT_OUTLET_NAME = "Outlet"; +const std::string EPOWERSWITCH_DEFAULT_OUTLET_STATUS = "Off"; #endif -- 2.52.0 From 130b1962b3232efd7fe4704284dcd7046e541d08 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 14:36:59 +0200 Subject: [PATCH 13/22] added comment --- src/device/ePowerSwitchEquipment.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index cd6fc4c..0f3b7d6 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -153,6 +153,10 @@ void ePowerSwitchEquipment::updateOutletNumber() { "Outlet number increasing, creating %d new outlet(s)", epicsOutletNumber - this->numberOfOutlet); + /* + This for loop will only iterate if the condition on top of this + comment is true + */ for (int i = this->numberOfOutlet; i < epicsOutletNumber; i++) { std::string epicsSetRecordName; { @@ -181,7 +185,10 @@ void ePowerSwitchEquipment::updateOutletNumber() { fMfe->Msg(MDEBUG, __FUNCTION__, "Outlet number decreasing, destroying %d outlet(s)", this->numberOfOutlet - epicsOutletNumber); - + /* + This for loop will only iterate if the condition on top of this + comment is true + */ for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { std::string requestedVarname; -- 2.52.0 From 96e75fe16b75a8b0c635c31ad9261a365fe17ecd Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 14:48:10 +0200 Subject: [PATCH 14/22] removing redundancy error message, and exiting if we are disconnected from midas --- src/device/ePowerSwitchEquipment.cpp | 37 ++++++++-------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 0f3b7d6..02c5efa 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -64,7 +64,6 @@ void ePowerSwitchEquipment::refreshOutlet(int outletId) { } std::string midasRequestedOutletState = std::string("Off"); MVOdbError ovbError; - int mepicscaReturnCode; fOdbEqVariables->RS(usernameVarname.c_str(), &midasUsername, true, midasUsername.length() + 1, &ovbError); if (ovbError.fError) { @@ -91,28 +90,18 @@ void ePowerSwitchEquipment::refreshOutlet(int outletId) { } std::string epicsCurrentOutletState; - mepicscaReturnCode = + int mepicscaReturnCode = this->outletGetRecords.at(outletId)->get(&epicsCurrentOutletState); - if (mepicscaReturnCode != CM_SUCCESS) { - fMfe->Msg(MERROR, __FUNCTION__, - "Couldn't get the value, skipping refreshing outlet %d. " - "Error code %d", - outletId, mepicscaReturnCode); + if (mepicscaReturnCode != CM_SUCCESS) return; - } if (epicsCurrentOutletState != midasRequestedOutletState) { mepicscaReturnCode = this->outletSetRecords.at(outletId)->put( &midasRequestedOutletState); - if (mepicscaReturnCode != CM_SUCCESS) { - fMfe->Msg(MERROR, __FUNCTION__, - "Couldn't put the value, skipping refreshing outlet %d. " - "Error code %d", - outletId, mepicscaReturnCode); + if (mepicscaReturnCode != CM_SUCCESS) return; - } } fOdbEqVariables->WS(currentVarname.c_str(), epicsCurrentOutletState.c_str(), @@ -133,20 +122,10 @@ void ePowerSwitchEquipment::refreshAllOutlets() { void ePowerSwitchEquipment::updateOutletNumber() { int epicsOutletNumber = 0; - if (!outletNumberRecord.connected()) { - fMfe->Msg(MERROR, __FUNCTION__, - "Couldn't connect to outlet number record."); - return; - } int returnCode = outletNumberRecord.get(&epicsOutletNumber); - if (returnCode < 0) { - fMfe->Msg(MERROR, __FUNCTION__, - "Couldn't get outlet number record. [ERROR_CODE : %d]\n " - "Skipping function execution", - returnCode); + if (returnCode != CM_SUCCESS) return; - } if (this->numberOfOutlet < epicsOutletNumber) fMfe->Msg(MDEBUG, __FUNCTION__, @@ -204,12 +183,16 @@ void ePowerSwitchEquipment::updateOutletNumber() { MVOdbError ovbError; fOdbEqVariables->Delete(requestedVarname.c_str(), &ovbError); - if (ovbError.fError) + if (ovbError.fError) { fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + exit(EXIT_FAILURE); + } fOdbEqVariables->Delete(currentVarname.c_str(), &ovbError); - if (ovbError.fError) + if (ovbError.fError) { fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + exit(EXIT_FAILURE); + } this->outletSetRecords.pop_back(); this->outletGetRecords.pop_back(); -- 2.52.0 From e7b09927cdf58baa274e6fc6378242faf1587148 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Fri, 1 May 2026 14:58:13 +0200 Subject: [PATCH 15/22] adding one to match outlet id --- src/device/ePowerSwitchEquipment.cpp | 33 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp index 02c5efa..5699373 100644 --- a/src/device/ePowerSwitchEquipment.cpp +++ b/src/device/ePowerSwitchEquipment.cpp @@ -42,19 +42,19 @@ void ePowerSwitchEquipment::refreshOutlet(int outletId) { { static const std::string str1 = "Outlet "; static const std::string str2 = " name"; - usernameVarname = insert(&str1, outletId, &str2); + usernameVarname = insert(&str1, outletId + 1, &str2); } std::string requestedVarname; { static const std::string str1 = "|-> "; static const std::string str2 = " requested"; - requestedVarname = insert(&str1, outletId, &str2); + requestedVarname = insert(&str1, outletId + 1, &str2); } std::string currentVarname; { static const std::string str1 = "\\-> "; static const std::string str2 = " current"; - currentVarname = insert(&str1, outletId, &str2); + currentVarname = insert(&str1, outletId + 1, &str2); } std::string midasUsername; { @@ -170,18 +170,33 @@ void ePowerSwitchEquipment::updateOutletNumber() { */ for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { - std::string requestedVarname; - std::string currentVarname; + std::string usernameVarname; { static const std::string str1 = "Outlet "; - static const std::string str2a = " current"; - static const std::string str2b = " requested"; - requestedVarname = insert(&str1, i, &str2a); - currentVarname = insert(&str1, i, &str2b); + static const std::string str2 = " name"; + usernameVarname = insert(&str1, i + 1, &str2); + } + std::string requestedVarname; + { + static const std::string str1 = "|-> "; + static const std::string str2 = " requested"; + requestedVarname = insert(&str1, i + 1, &str2); + } + std::string currentVarname; + { + static const std::string str1 = "\\-> "; + static const std::string str2 = " current"; + currentVarname = insert(&str1, i + 1, &str2); } MVOdbError ovbError; + fOdbEqVariables->Delete(usernameVarname.c_str(), &ovbError); + if (ovbError.fError) { + fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); + exit(EXIT_FAILURE); + } + fOdbEqVariables->Delete(requestedVarname.c_str(), &ovbError); if (ovbError.fError) { fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); -- 2.52.0 From 17b4d04abdaa05867f7a7f38e3583faafcad0d7e Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 4 May 2026 09:08:07 +0200 Subject: [PATCH 16/22] adding install makefile --- .gitignore | 1 - Makefile | 0 2 files changed, 1 deletion(-) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 6986c74..a892224 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .vscode/ CMakeCache.txt CMakeFiles -Makefile cmake_install.cmake midas.log ePowerSwitchFront diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 -- 2.52.0 From 3f8ae7f15881f2f562382518d288581075291a55 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 4 May 2026 09:13:03 +0200 Subject: [PATCH 17/22] reverting --- .gitignore | 1 + Makefile | 0 2 files changed, 1 insertion(+) delete mode 100644 Makefile diff --git a/.gitignore b/.gitignore index a892224..309f4e5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ cmake_install.cmake midas.log ePowerSwitchFront build/ +Makefile \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index e69de29..0000000 -- 2.52.0 From 0228dac3d3b5a52a0994bfc98f65a24289b7500d Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 8 Jun 2026 08:51:04 +0200 Subject: [PATCH 18/22] grace perriode added to prevent resetting --- CMakeLists.txt | 15 +- include/ePowerSwitchFront.h | 60 ------- src/device/ePowerSwitchEquipment.cpp | 217 ----------------------- src/device/ePowerSwitchEquipment.h | 50 ------ src/device/ePowerSwitchEquipmentConfig.h | 13 -- src/frontend/ePowerSwitchFrontend.cpp | 4 +- submodule/mepicsca | 2 +- 7 files changed, 11 insertions(+), 350 deletions(-) delete mode 100644 include/ePowerSwitchFront.h delete mode 100644 src/device/ePowerSwitchEquipment.cpp delete mode 100644 src/device/ePowerSwitchEquipment.h delete mode 100644 src/device/ePowerSwitchEquipmentConfig.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 70ce644..123aae6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ add_subdirectory(submodule/mepicsca) add_compile_options( -Wall -Wformat=2 - -O3 + -g -Wno-format-nonliteral -Wno-strict-aliasing -Wuninitialized @@ -49,19 +49,20 @@ find_package(Midas REQUIRED) ################################################################################ add_library( - ePowerSwitchEquipment - src/device/ePowerSwitchEquipment.cpp + powerSwitch + src/device/powerSwitch.cpp + src/utils/outlet.cpp ) set_property( TARGET - ePowerSwitchEquipment + powerSwitch PROPERTY CXX_STANDARD 17 ) target_link_libraries( - ePowerSwitchEquipment + powerSwitch PRIVATE midas::mfe m_epics_ca @@ -69,7 +70,7 @@ target_link_libraries( ) target_include_directories( - ePowerSwitchEquipment + powerSwitch PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE @@ -113,7 +114,7 @@ target_include_directories( target_link_libraries( ePowerSwitchFrontend PRIVATE - ePowerSwitchEquipment + powerSwitch midas::mfe m_epics_ca ${LIBS} diff --git a/include/ePowerSwitchFront.h b/include/ePowerSwitchFront.h deleted file mode 100644 index f4298e6..0000000 --- a/include/ePowerSwitchFront.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef EPOWERSWITCH_FRONTEND_H -#define EPOWERSWITCH_FRONTEND_H - -#include "m_epics_ca.h" -#include "tmfe.h" -#include - -class ePowerSwitchEquipment : public TMFeEquipment { - - public: - /** - * @brief constructor - * - * @param equipmentName name show on Midas for the equipment - * @param equipmentFileName file name for automatically tagged message - */ - ePowerSwitchEquipment(std::string equipmentName, - const char *equipmentFileName); - - /** - * @brief called periodically by Midas - */ - void HandlePeriodic(); - - private: - std::vector *> outletSetRecords; - std::vector *> outletGetRecords; - mEpicsCa outletNumberRecord; - int numberOfOutlet; - - /** - * @brief refresh information about the given socket ID - * - * @param socketId which socket to refresh - */ - void refreshSocket(int socketId); - - /** - * @brief refresh information about all the available sockets - */ - void refreshAllSockets(); - - /** - * @brief detect and modify the current socket pool in case of change - */ - void updateSocketNumber(); -}; - -class ePowerSwitchFrontend : public TMFrontend { - public: - /** - * @brief constructor - * - * @param frontendName name shown on Midas for the frontend - * @param equipmentName name shown on Midas for the equipment - */ - ePowerSwitchFrontend(std::string frontendName, std::string equipmentName); -}; - -#endif \ No newline at end of file diff --git a/src/device/ePowerSwitchEquipment.cpp b/src/device/ePowerSwitchEquipment.cpp deleted file mode 100644 index 5699373..0000000 --- a/src/device/ePowerSwitchEquipment.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "ePowerSwitchEquipment.h" -#include "ePowerSwitchEquipmentConfig.h" -#include "tmfe.h" -#include - -/** - * @brief Insert a integer value between two string - * @param str1 first string - * @param int value to insert - * @param str2 second string - * - * @return a new string instance - */ -std::string insert(const std::string *str1, int value, - const std::string *str2) { - return *str1 + std::to_string(value) + *str2; -} - -ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, - const char *equipmentFileName) - : TMFeEquipment(equipmentName.c_str(), equipmentFileName), - outletNumberRecord(mEpicsCa( - std::string_view(EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX))) { - - fEqConfPeriodMilliSec = 1000; // refresh rate of midas frontend - fEqConfLogHistory = - 60; // enable history system, generate one event per minutes - fEqConfReadOnlyWhenRunning = false; // allow to write values when running - fEqConfWriteEventsToOdb = true; // allow to write event to the odb - - this->numberOfOutlet = 0; -} - -void ePowerSwitchEquipment::HandlePeriodic() { - updateOutletNumber(); - refreshAllOutlets(); -} - -void ePowerSwitchEquipment::refreshOutlet(int outletId) { - - std::string usernameVarname; - { - static const std::string str1 = "Outlet "; - static const std::string str2 = " name"; - usernameVarname = insert(&str1, outletId + 1, &str2); - } - std::string requestedVarname; - { - static const std::string str1 = "|-> "; - static const std::string str2 = " requested"; - requestedVarname = insert(&str1, outletId + 1, &str2); - } - std::string currentVarname; - { - static const std::string str1 = "\\-> "; - static const std::string str2 = " current"; - currentVarname = insert(&str1, outletId + 1, &str2); - } - std::string midasUsername; - { - static const std::string str1 = "Outlet "; - static const std::string str2 = ""; - midasUsername = insert(&str1, outletId, &str2); - } - std::string midasRequestedOutletState = std::string("Off"); - MVOdbError ovbError; - fOdbEqVariables->RS(usernameVarname.c_str(), &midasUsername, true, - midasUsername.length() + 1, &ovbError); - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } - - fOdbEqVariables->RS(requestedVarname.c_str(), &midasRequestedOutletState, - true, midasRequestedOutletState.length() + 1, - &ovbError); - - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } - - std::string defaultCurrentState = "unknow"; - fOdbEqVariables->RS(currentVarname.c_str(), &defaultCurrentState, true, - defaultCurrentState.length() + 1, &ovbError); - - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } - - std::string epicsCurrentOutletState; - int mepicscaReturnCode = - this->outletGetRecords.at(outletId)->get(&epicsCurrentOutletState); - - if (mepicscaReturnCode != CM_SUCCESS) - return; - - if (epicsCurrentOutletState != midasRequestedOutletState) { - mepicscaReturnCode = this->outletSetRecords.at(outletId)->put( - &midasRequestedOutletState); - - if (mepicscaReturnCode != CM_SUCCESS) - return; - } - - fOdbEqVariables->WS(currentVarname.c_str(), epicsCurrentOutletState.c_str(), - epicsCurrentOutletState.length() + 1, &ovbError); - - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } -} - -void ePowerSwitchEquipment::refreshAllOutlets() { - for (int i = 0; i < this->numberOfOutlet; i++) { - refreshOutlet(i); - } -} - -void ePowerSwitchEquipment::updateOutletNumber() { - int epicsOutletNumber = 0; - - int returnCode = outletNumberRecord.get(&epicsOutletNumber); - - if (returnCode != CM_SUCCESS) - return; - - if (this->numberOfOutlet < epicsOutletNumber) - fMfe->Msg(MDEBUG, __FUNCTION__, - "Outlet number increasing, creating %d new outlet(s)", - epicsOutletNumber - this->numberOfOutlet); - - /* - This for loop will only iterate if the condition on top of this - comment is true - */ - for (int i = this->numberOfOutlet; i < epicsOutletNumber; i++) { - std::string epicsSetRecordName; - { - static const std::string *str1 = &EPOWERSWITCH_OUTLET_SET_PREFIX; - static const std::string str2 = ""; - epicsSetRecordName = insert(str1, i, &str2); - } - - this->outletSetRecords.push_back( - std::make_unique>( - epicsSetRecordName.c_str())); - - std::string epicsGetRecordName; - { - static const std::string *str1 = &EPOWERSWITCH_OUTLET_GET_PREFIX; - static const std::string str2 = ""; - epicsGetRecordName = insert(str1, i, &str2); - } - - this->outletGetRecords.push_back( - std::make_unique>( - epicsGetRecordName.c_str())); - } - - if (this->numberOfOutlet > epicsOutletNumber) - fMfe->Msg(MDEBUG, __FUNCTION__, - "Outlet number decreasing, destroying %d outlet(s)", - this->numberOfOutlet - epicsOutletNumber); - /* - This for loop will only iterate if the condition on top of this - comment is true - */ - for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { - - std::string usernameVarname; - { - static const std::string str1 = "Outlet "; - static const std::string str2 = " name"; - usernameVarname = insert(&str1, i + 1, &str2); - } - std::string requestedVarname; - { - static const std::string str1 = "|-> "; - static const std::string str2 = " requested"; - requestedVarname = insert(&str1, i + 1, &str2); - } - std::string currentVarname; - { - static const std::string str1 = "\\-> "; - static const std::string str2 = " current"; - currentVarname = insert(&str1, i + 1, &str2); - } - - MVOdbError ovbError; - - fOdbEqVariables->Delete(usernameVarname.c_str(), &ovbError); - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } - - fOdbEqVariables->Delete(requestedVarname.c_str(), &ovbError); - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } - - fOdbEqVariables->Delete(currentVarname.c_str(), &ovbError); - if (ovbError.fError) { - fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); - exit(EXIT_FAILURE); - } - - this->outletSetRecords.pop_back(); - this->outletGetRecords.pop_back(); - } - - this->numberOfOutlet = epicsOutletNumber; -} diff --git a/src/device/ePowerSwitchEquipment.h b/src/device/ePowerSwitchEquipment.h deleted file mode 100644 index e514de2..0000000 --- a/src/device/ePowerSwitchEquipment.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef EPOWERSWITCH_EQUIPMENT_H -#define EPOWERSWITCH_EQUIPMENT_H - -#include "m_epics_ca.h" -#include "tmfe.h" -#include - -class ePowerSwitchEquipment : public TMFeEquipment { - - public: - /** - * @brief constructor - * - * @param equipmentName name show on Midas for the equipment - * @param equipmentFileName file name for automatically tagged message - */ - ePowerSwitchEquipment(std::string equipmentName, - const char *equipmentFileName); - - /** - * @brief called periodically by Midas - */ - void HandlePeriodic(); - - private: - std::vector>> outletSetRecords; - std::vector>> outletGetRecords; - std::vector outletNames; - mEpicsCa outletNumberRecord; - int numberOfOutlet; - - /** - * @brief refresh information about the given outlet ID - * - * @param outletId which outlet to refresh - */ - void refreshOutlet(int outletId); - - /** - * @brief refresh information about all the available outlets - */ - void refreshAllOutlets(); - - /** - * @brief detect and modify the current outlet pool in case of change - */ - void updateOutletNumber(); -}; - -#endif \ No newline at end of file diff --git a/src/device/ePowerSwitchEquipmentConfig.h b/src/device/ePowerSwitchEquipmentConfig.h deleted file mode 100644 index e4e83f1..0000000 --- a/src/device/ePowerSwitchEquipmentConfig.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef EPOWERSWITCH_CONFIG_H -#define EPOWERSWITCH_CONFIG_H -#include - -const std::string EPOWERSWITCH_OUTLET_SET_PREFIX = "ePowerSwitch_set_outlet_"; -const std::string EPOWERSWITCH_OUTLET_GET_PREFIX = "ePowerSwitch_get_outlet_"; -const std::string EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX = - "ePowerSwitch_config_maxOutlet"; - -const std::string EPOWERSWITCH_DEFAULT_OUTLET_NAME = "Outlet"; -const std::string EPOWERSWITCH_DEFAULT_OUTLET_STATUS = "Off"; - -#endif diff --git a/src/frontend/ePowerSwitchFrontend.cpp b/src/frontend/ePowerSwitchFrontend.cpp index 29b06a9..117d47d 100644 --- a/src/frontend/ePowerSwitchFrontend.cpp +++ b/src/frontend/ePowerSwitchFrontend.cpp @@ -1,5 +1,5 @@ #include "ePowerSwitchFrontend.h" -#include "../device/ePowerSwitchEquipment.h" +#include "../device/powerSwitch.h" #include "ePowerSwitchFrontendConfig.h" #include "tmfe.h" @@ -45,5 +45,5 @@ int main(int argc, char *argv[]) { ePowerSwitchFrontend::ePowerSwitchFrontend(std::string frontendName, std::string equipmentName) { FeSetName(frontendName.c_str()); - FeAddEquipment(new ePowerSwitchEquipment(equipmentName.c_str(), __FILE__)); + FeAddEquipment(new powerSwitch(equipmentName.c_str(), __FILE__)); } \ No newline at end of file diff --git a/submodule/mepicsca b/submodule/mepicsca index 419df88..b6aca41 160000 --- a/submodule/mepicsca +++ b/submodule/mepicsca @@ -1 +1 @@ -Subproject commit 419df88dde85d8dc3150c7632c4214950b92c881 +Subproject commit b6aca4174e2789cb1bf4a3f56b8a26446994d961 -- 2.52.0 From 6f3807f13de59960fbb58801a3a20a9119d1ddff Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 8 Jun 2026 08:51:33 +0200 Subject: [PATCH 19/22] new version of powerSwitch --- src/device/powerSwitch.cpp | 105 +++++++++++++++++ src/device/powerSwitch.h | 25 ++++ src/device/powerSwitchConfig.h | 28 +++++ src/utils/outlet.cpp | 202 +++++++++++++++++++++++++++++++++ src/utils/outlet.h | 44 +++++++ 5 files changed, 404 insertions(+) create mode 100644 src/device/powerSwitch.cpp create mode 100644 src/device/powerSwitch.h create mode 100644 src/device/powerSwitchConfig.h create mode 100644 src/utils/outlet.cpp create mode 100644 src/utils/outlet.h diff --git a/src/device/powerSwitch.cpp b/src/device/powerSwitch.cpp new file mode 100644 index 0000000..2ca08a4 --- /dev/null +++ b/src/device/powerSwitch.cpp @@ -0,0 +1,105 @@ +#include "powerSwitch.h" +#include "odbxx.h" +#include "powerSwitchConfig.h" +#include "tmfe.h" +#include + +#include + +/** + * @brief Insert a integer value between two string + * @param str1 first string + * @param int value to insert + * @param str2 second string + * + * @return a new string instance + */ +std::string insert(const std::string *str1, int value, + const std::string *str2) { + return *str1 + std::to_string(value) + *str2; +} + +powerSwitch::powerSwitch(std::string equipmentName, + const char *equipmentFilename) + : TMFeEquipment(equipmentName.c_str(), equipmentFilename), + outletNumberRecord(mEpicsCa(EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX)) { + fEqConfReadOnlyWhenRunning = false; + + this->equipmentPath = std::string("/Equipment/") + equipmentName; +} + +void powerSwitch::HandlePeriodic() { + + updateOutletNumber(); + midas::odb o(this->equipmentPath); + + for (int i = 0; i < this->numberOfOutlet; i++) { + Outlet *outlet = &this->outlets.at(i); + + if (outlet->commandHasChange()) { + o[COMMAND_PATH.c_str()][i] = outlet->getCommand(); + } + o[READBACK_PATH.c_str()][i] = outlet->getState(); + } +} +TMFeResult powerSwitch::HandleInit(const std::vector &args) { + + midas::odb o = { + {SETTING_DIR.c_str(), {{EDITABLE_VARNAME.c_str(), COMMAND_VARNAME}}}}; + + o.connect(this->equipmentPath.c_str()); + + midas::odb to_watch(this->equipmentPath + SLASH + VARIABLES_DIR + SLASH + + COMMAND_VARNAME); + + to_watch.watch( + [&](midas::odb &arg) { this->sendCommand(arg.get_last_index()); }); + return TMFeOk(); +} +void powerSwitch::updateOutletNumber() { + int newNumberOfOutlet = 0; + + int returnCode = outletNumberRecord.get(&newNumberOfOutlet); + if (returnCode != CM_SUCCESS) { + fMfe->Msg(MERROR, __FUNCTION__, "Unable to read outlet record number"); + } + + if (this->numberOfOutlet < newNumberOfOutlet) + fMfe->Msg(MDEBUG, __FUNCTION__, + "Outlet number increasing, creating %d new outlet(s)", + newNumberOfOutlet - this->numberOfOutlet); + + for (int i = this->numberOfOutlet; i < newNumberOfOutlet; i++) { + std::string epicsSetRecordName; + { + static const std::string *str1 = &EPOWERSWITCH_OUTLET_SET_PREFIX; + static const std::string str2 = ""; + epicsSetRecordName = insert(str1, i + 1, &str2); + } + std::string epicsGetRecordName; + { + static const std::string *str1 = &EPOWERSWITCH_OUTLET_GET_PREFIX; + static const std::string str2 = ""; + epicsGetRecordName = insert(str1, i + 1, &str2); + } + this->outlets.emplace_back(i, epicsGetRecordName, epicsSetRecordName); + } + + if (this->numberOfOutlet > newNumberOfOutlet) + fMfe->Msg(MDEBUG, __FUNCTION__, + "Outlet number decreasing, destroying %d outlet(s)", + this->numberOfOutlet - newNumberOfOutlet); + + for (int i = newNumberOfOutlet; i < this->numberOfOutlet; i++) { + this->outlets.pop_back(); + } + + this->numberOfOutlet = newNumberOfOutlet; +} + +void powerSwitch::sendCommand(int index) { + midas::odb o(this->equipmentPath); + std::string command = o[COMMAND_PATH.c_str()][index]; + Outlet *outlet = &outlets.at(index); + outlet->setState(command); +} diff --git a/src/device/powerSwitch.h b/src/device/powerSwitch.h new file mode 100644 index 0000000..1acd9a4 --- /dev/null +++ b/src/device/powerSwitch.h @@ -0,0 +1,25 @@ +#ifndef POWER_SWITCH_H +#define POWER_SWITCH_H + +#include "../utils/outlet.h" +#include "tmfe.h" +#include + +class powerSwitch : public TMFeEquipment { + public: + powerSwitch(std::string equipmentName, const char *equipmentFilename); + void HandlePeriodic(); + TMFeResult HandleInit(const std::vector &args); + + private: + std::vector outlets; + mEpicsCa outletNumberRecord; + int numberOfOutlet; + std::string equipmentPath; + + void updateOutletNumber(); + + void sendCommand(int index); +}; + +#endif \ No newline at end of file diff --git a/src/device/powerSwitchConfig.h b/src/device/powerSwitchConfig.h new file mode 100644 index 0000000..4d9bfd5 --- /dev/null +++ b/src/device/powerSwitchConfig.h @@ -0,0 +1,28 @@ +#ifndef POWER_SWITCH_CONFIG_H +#define POWER_SWITCH_CONFIG_H + +#include + +const std::string EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX = + "ePowerSwitch_config_maxOutlet"; + +const std::string VARIABLES_DIR = "Variables"; +const std::string SETTING_DIR = "Settings"; +const std::string COMMAND_VARNAME = "Command"; +const std::string READBACK_VARNAME = "Readback"; + +const std::string SLASH = "/"; + +const std::string EPOWERSWITCH_OUTLET_SET_PREFIX = "ePowerSwitch_set_outlet_"; +const std::string EPOWERSWITCH_OUTLET_GET_PREFIX = "ePowerSwitch_get_outlet_"; + +const std::string EDITABLE_VARNAME = std::string("Editable"); + +// ################################################## +// Paths names : do not modify +// ################################################## + +const std::string COMMAND_PATH = VARIABLES_DIR + SLASH + COMMAND_VARNAME; +const std::string READBACK_PATH = VARIABLES_DIR + SLASH + READBACK_VARNAME; + +#endif \ No newline at end of file diff --git a/src/utils/outlet.cpp b/src/utils/outlet.cpp new file mode 100644 index 0000000..841be75 --- /dev/null +++ b/src/utils/outlet.cpp @@ -0,0 +1,202 @@ +#include "outlet.h" +#include "m_epics_ca.h" +#include "odbxx.h" +#include "tmfe.h" +#include + +Outlet::Outlet(int index, std::string inputRecordName, + std::string outputRecordName) + : input(mEpicsCa(inputRecordName)), + output(mEpicsCa(outputRecordName)) { + this->index = index; + this->innerState = State::UNKNOW; + + this->isOutputConnected = true; + this->isInputConnected = true; + this->gracePeriod = 3; +} + +std::string Outlet::getState() { + this->updateState(); + return this->stateToString(this->innerState); +} + +std::string Outlet::getCommand() { + State command = this->_getCommand(); + this->lastCommand = command; + return this->stateToString(command); +} + +bool Outlet::commandHasChange() { + return this->lastCommand != this->_getCommand(); +} + +void Outlet::setState(State state) { + printf("set a new states \n"); + this->buffered = state; + this->updateState(); +} + +void Outlet::setState(std::string state) { + this->setState(this->stringToState(state)); +} + +void Outlet::turnOn() { + std::string msg = "On"; + int returnCode = this->output.put(&msg); + if (returnCode != CM_SUCCESS) + TMFE::Instance()->Msg( + MERROR, __FUNCTION__, + "Outlet %d : Error %d : unable to write into output record", + this->index, returnCode); +} + +void Outlet::turnOff() { + std::string msg = "Off"; + int returnCode = this->output.put(&msg); + if (returnCode != CM_SUCCESS) + TMFE::Instance()->Msg( + MERROR, __FUNCTION__, + "Outlet %d : Error %d : unable to write into output record", + this->index, returnCode); +} + +void Outlet::restart() { + std::string msg = "Restart"; + int returnCode = this->output.put(&msg); + if (returnCode != CM_SUCCESS) + TMFE::Instance()->Msg( + MERROR, __FUNCTION__, + "Outlet %d : Error %d : unable to write into output record", + this->index, returnCode); +} + +void Outlet::updateState() { + bool outputConnected = this->output.connected(); + bool inputConnected = this->input.connected(); + + if (!outputConnected && this->isOutputConnected) { + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Outlet %d : Output channel disconnected", + this->index); + } + + if (!inputConnected && this->isInputConnected) { + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Outlet %d : Input channel disconnected", + this->index); + } + + this->isOutputConnected = outputConnected; + this->isInputConnected = inputConnected; + + if (!outputConnected || !inputConnected) { + // Error message are above + return; + } + + if (this->gracePeriod > 0) { + this->gracePeriod--; + buffered.reset(); + } + + std::string value; + + int returnCode = this->input.get(&value); + if (returnCode != CM_SUCCESS) { + TMFE::Instance()->Msg( + MERROR, __FUNCTION__, + "Outlet %d : Error %d : unable to read from input record", + this->index, returnCode); + } + + this->innerState = stringToState(value); + + if (buffered.has_value()) { + State state = buffered.value(); + printf("update state to \"%s\" sur l'outlet %d\n", value.c_str(), + this->index); + switch (this->innerState) { + case State::ON: + if (state == State::OFF) + this->turnOff(); + if (state == State::RST) + this->restart(); + buffered.reset(); + break; + case State::OFF: + if (state == State::ON) + this->turnOn(); + if (state == State::RST) + this->restart(); + buffered.reset(); + break; + case State::RST: + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Outlet %d in restarting state, command " + "pending in a buffered state", + this->index); + break; + case State::UNKNOW: + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "Outlet %d : Unknow state", this->index); + if (state == State::ON) + this->turnOn(); + if (state == State::OFF) + this->turnOff(); + if (state == State::RST) + this->restart(); + buffered.reset(); + break; + + default: // This state doesn't exist + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Outlet %d : FATAL ERROR : unvalide state", + this->index); + exit(EXIT_FAILURE); + break; + } + } +} + +Outlet::State Outlet::stringToState(std::string value) { + if (value == "ON" || value == "On") { + return State::ON; + } + if (value == "OFF" || value == "Off") { + return State::OFF; + } + if (value == "RST" || value == "Rst" || value == "Res" || value == "RES" || + value == "RESTART" || value == "Restart") { + return State::RST; + } + return State::UNKNOW; +} + +std::string Outlet::stateToString(State state) { + switch (state) { + case State::ON: + return std::string("On"); + break; + case State::OFF: + return std::string("Off"); + break; + case State::RST: + return std::string("Restart"); + break; + default: + return std::string("Unknow"); + break; + }; +} + +Outlet::State Outlet::_getCommand() { + std::string value; + int returnCode = this->output.get(&value); + if (returnCode != CM_SUCCESS) + TMFE::Instance()->Msg( + MERROR, __FUNCTION__, + "Outlet %d : Error %d : unable to read from output record", + this->index, returnCode); + return stringToState(value); +} diff --git a/src/utils/outlet.h b/src/utils/outlet.h new file mode 100644 index 0000000..bece194 --- /dev/null +++ b/src/utils/outlet.h @@ -0,0 +1,44 @@ +#ifndef OUTLET_H +#define OUTLET_H + +#include "m_epics_ca.h" + +class Outlet { + public: + Outlet(int index, std::string inputRecordName, + std::string outputRecordName); + + enum class State { ON, OFF, RST, UNKNOW }; + + Outlet(Outlet &&other) noexcept = default; + + std::string getState(); + std::string getCommand(); + bool commandHasChange(); + void setState(State state); + void setState(std::string state); + + private: + mEpicsCa input; + mEpicsCa output; + + bool isInputConnected; + bool isOutputConnected; + + int gracePeriod; + + std::optional buffered; + State innerState; + int index; + + void turnOn(); + void turnOff(); + void restart(); + void updateState(); + Outlet::State stringToState(std::string value); + std::string stateToString(State state); + State _getCommand(); + State lastCommand; +}; + +#endif \ No newline at end of file -- 2.52.0 From 95a6f1f371cc75978f5843770c3432461dc60d1a Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 8 Jun 2026 09:02:46 +0200 Subject: [PATCH 20/22] outlet update comment --- src/utils/outlet.cpp | 5 ++--- src/utils/outlet.h | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/utils/outlet.cpp b/src/utils/outlet.cpp index 841be75..953cb7c 100644 --- a/src/utils/outlet.cpp +++ b/src/utils/outlet.cpp @@ -32,7 +32,6 @@ bool Outlet::commandHasChange() { } void Outlet::setState(State state) { - printf("set a new states \n"); this->buffered = state; this->updateState(); } @@ -95,6 +94,7 @@ void Outlet::updateState() { return; } + // Adding a grace period to prevent reseting at start if (this->gracePeriod > 0) { this->gracePeriod--; buffered.reset(); @@ -114,8 +114,7 @@ void Outlet::updateState() { if (buffered.has_value()) { State state = buffered.value(); - printf("update state to \"%s\" sur l'outlet %d\n", value.c_str(), - this->index); + switch (this->innerState) { case State::ON: if (state == State::OFF) diff --git a/src/utils/outlet.h b/src/utils/outlet.h index bece194..021242b 100644 --- a/src/utils/outlet.h +++ b/src/utils/outlet.h @@ -12,10 +12,30 @@ class Outlet { Outlet(Outlet &&other) noexcept = default; + /** + * @brief get the current state of the device by reading it + * @return the current state + */ std::string getState(); + + /** + * @brief get the value of the command stored in the command buffer + * @return the current command state + */ std::string getCommand(); + /** + * @brief return true if the last value readed from this object if not equal + * to the current device state + */ bool commandHasChange(); + /** + * @brief set to a new state the device + */ void setState(State state); + /** + * @brief set to a new state the device. If string not recognize, will put + * UNKNOW to the outlet state + */ void setState(std::string state); private: -- 2.52.0 From 6fceb10f496b243bd8f6f9164323587eba6dc6e7 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 8 Jun 2026 09:14:52 +0200 Subject: [PATCH 21/22] finished, ready for code review --- CMakeLists.txt | 32 +++---- src/device/powerSwitch.cpp | 105 ---------------------- src/device/powerSwitch.h | 25 ------ src/device/powerSwitchConfig.h | 28 ------ src/frontend/ePowerSwitchFrontend.cpp | 49 ---------- src/frontend/ePowerSwitchFrontend.h | 17 ---- src/frontend/ePowerSwitchFrontendConfig.h | 7 -- 7 files changed, 16 insertions(+), 247 deletions(-) delete mode 100644 src/device/powerSwitch.cpp delete mode 100644 src/device/powerSwitch.h delete mode 100644 src/device/powerSwitchConfig.h delete mode 100644 src/frontend/ePowerSwitchFrontend.cpp delete mode 100644 src/frontend/ePowerSwitchFrontend.h delete mode 100644 src/frontend/ePowerSwitchFrontendConfig.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 123aae6..4a2301f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,20 +49,20 @@ find_package(Midas REQUIRED) ################################################################################ add_library( - powerSwitch - src/device/powerSwitch.cpp + power_switch + src/device/power_switch.cpp src/utils/outlet.cpp ) set_property( TARGET - powerSwitch + power_switch PROPERTY CXX_STANDARD 17 ) target_link_libraries( - powerSwitch + power_switch PRIVATE midas::mfe m_epics_ca @@ -70,7 +70,7 @@ target_link_libraries( ) target_include_directories( - powerSwitch + power_switch PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE @@ -87,20 +87,20 @@ target_include_directories( ## Frontend ################################################################################ -add_executable(ePowerSwitchFrontend - src/frontend/ePowerSwitchFrontend.cpp +add_executable(power_switch_scfe + src/frontend/power_switch_scfe.cpp ) set_property( TARGET - ePowerSwitchFrontend + power_switch_scfe PROPERTY CXX_STANDARD 17 ) target_include_directories( - ePowerSwitchFrontend + power_switch_scfe PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE @@ -112,15 +112,15 @@ target_include_directories( ) target_link_libraries( - ePowerSwitchFrontend + power_switch_scfe PRIVATE - powerSwitch + power_switch midas::mfe m_epics_ca ${LIBS} ) -# install( -# TARGETS -# ePowerSwitchFrontend -# RUNTIME DESTINATION bin -# ) +install( + TARGETS + power_switch_scfe + RUNTIME DESTINATION bin +) diff --git a/src/device/powerSwitch.cpp b/src/device/powerSwitch.cpp deleted file mode 100644 index 2ca08a4..0000000 --- a/src/device/powerSwitch.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "powerSwitch.h" -#include "odbxx.h" -#include "powerSwitchConfig.h" -#include "tmfe.h" -#include - -#include - -/** - * @brief Insert a integer value between two string - * @param str1 first string - * @param int value to insert - * @param str2 second string - * - * @return a new string instance - */ -std::string insert(const std::string *str1, int value, - const std::string *str2) { - return *str1 + std::to_string(value) + *str2; -} - -powerSwitch::powerSwitch(std::string equipmentName, - const char *equipmentFilename) - : TMFeEquipment(equipmentName.c_str(), equipmentFilename), - outletNumberRecord(mEpicsCa(EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX)) { - fEqConfReadOnlyWhenRunning = false; - - this->equipmentPath = std::string("/Equipment/") + equipmentName; -} - -void powerSwitch::HandlePeriodic() { - - updateOutletNumber(); - midas::odb o(this->equipmentPath); - - for (int i = 0; i < this->numberOfOutlet; i++) { - Outlet *outlet = &this->outlets.at(i); - - if (outlet->commandHasChange()) { - o[COMMAND_PATH.c_str()][i] = outlet->getCommand(); - } - o[READBACK_PATH.c_str()][i] = outlet->getState(); - } -} -TMFeResult powerSwitch::HandleInit(const std::vector &args) { - - midas::odb o = { - {SETTING_DIR.c_str(), {{EDITABLE_VARNAME.c_str(), COMMAND_VARNAME}}}}; - - o.connect(this->equipmentPath.c_str()); - - midas::odb to_watch(this->equipmentPath + SLASH + VARIABLES_DIR + SLASH + - COMMAND_VARNAME); - - to_watch.watch( - [&](midas::odb &arg) { this->sendCommand(arg.get_last_index()); }); - return TMFeOk(); -} -void powerSwitch::updateOutletNumber() { - int newNumberOfOutlet = 0; - - int returnCode = outletNumberRecord.get(&newNumberOfOutlet); - if (returnCode != CM_SUCCESS) { - fMfe->Msg(MERROR, __FUNCTION__, "Unable to read outlet record number"); - } - - if (this->numberOfOutlet < newNumberOfOutlet) - fMfe->Msg(MDEBUG, __FUNCTION__, - "Outlet number increasing, creating %d new outlet(s)", - newNumberOfOutlet - this->numberOfOutlet); - - for (int i = this->numberOfOutlet; i < newNumberOfOutlet; i++) { - std::string epicsSetRecordName; - { - static const std::string *str1 = &EPOWERSWITCH_OUTLET_SET_PREFIX; - static const std::string str2 = ""; - epicsSetRecordName = insert(str1, i + 1, &str2); - } - std::string epicsGetRecordName; - { - static const std::string *str1 = &EPOWERSWITCH_OUTLET_GET_PREFIX; - static const std::string str2 = ""; - epicsGetRecordName = insert(str1, i + 1, &str2); - } - this->outlets.emplace_back(i, epicsGetRecordName, epicsSetRecordName); - } - - if (this->numberOfOutlet > newNumberOfOutlet) - fMfe->Msg(MDEBUG, __FUNCTION__, - "Outlet number decreasing, destroying %d outlet(s)", - this->numberOfOutlet - newNumberOfOutlet); - - for (int i = newNumberOfOutlet; i < this->numberOfOutlet; i++) { - this->outlets.pop_back(); - } - - this->numberOfOutlet = newNumberOfOutlet; -} - -void powerSwitch::sendCommand(int index) { - midas::odb o(this->equipmentPath); - std::string command = o[COMMAND_PATH.c_str()][index]; - Outlet *outlet = &outlets.at(index); - outlet->setState(command); -} diff --git a/src/device/powerSwitch.h b/src/device/powerSwitch.h deleted file mode 100644 index 1acd9a4..0000000 --- a/src/device/powerSwitch.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef POWER_SWITCH_H -#define POWER_SWITCH_H - -#include "../utils/outlet.h" -#include "tmfe.h" -#include - -class powerSwitch : public TMFeEquipment { - public: - powerSwitch(std::string equipmentName, const char *equipmentFilename); - void HandlePeriodic(); - TMFeResult HandleInit(const std::vector &args); - - private: - std::vector outlets; - mEpicsCa outletNumberRecord; - int numberOfOutlet; - std::string equipmentPath; - - void updateOutletNumber(); - - void sendCommand(int index); -}; - -#endif \ No newline at end of file diff --git a/src/device/powerSwitchConfig.h b/src/device/powerSwitchConfig.h deleted file mode 100644 index 4d9bfd5..0000000 --- a/src/device/powerSwitchConfig.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef POWER_SWITCH_CONFIG_H -#define POWER_SWITCH_CONFIG_H - -#include - -const std::string EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX = - "ePowerSwitch_config_maxOutlet"; - -const std::string VARIABLES_DIR = "Variables"; -const std::string SETTING_DIR = "Settings"; -const std::string COMMAND_VARNAME = "Command"; -const std::string READBACK_VARNAME = "Readback"; - -const std::string SLASH = "/"; - -const std::string EPOWERSWITCH_OUTLET_SET_PREFIX = "ePowerSwitch_set_outlet_"; -const std::string EPOWERSWITCH_OUTLET_GET_PREFIX = "ePowerSwitch_get_outlet_"; - -const std::string EDITABLE_VARNAME = std::string("Editable"); - -// ################################################## -// Paths names : do not modify -// ################################################## - -const std::string COMMAND_PATH = VARIABLES_DIR + SLASH + COMMAND_VARNAME; -const std::string READBACK_PATH = VARIABLES_DIR + SLASH + READBACK_VARNAME; - -#endif \ No newline at end of file diff --git a/src/frontend/ePowerSwitchFrontend.cpp b/src/frontend/ePowerSwitchFrontend.cpp deleted file mode 100644 index 117d47d..0000000 --- a/src/frontend/ePowerSwitchFrontend.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "ePowerSwitchFrontend.h" -#include "../device/powerSwitch.h" -#include "ePowerSwitchFrontendConfig.h" -#include "tmfe.h" - -int main(int argc, char *argv[]) { - - if (argv[0][0] == '.') { - TMFE::Instance()->Msg(MERROR, __FUNCTION__, - "Relative paths are strongly discouraged; " - "please use an absolute path."); - } - - std::string frontendName; - std::string equipmentName; - - if (argc == 1) { - frontendName = DEFAULT_FRONTEND_NAME; - TMFE::Instance()->Msg(MINFO, __FUNCTION__, - "No frontend name provided; %s will be used", - DEFAULT_FRONTEND_NAME); - equipmentName = DEFAULT_EQUIPMENT_NAME; - TMFE::Instance()->Msg(MINFO, __FUNCTION__, - "No equipment name provided; %s will be used", - DEFAULT_EQUIPMENT_NAME); - } - if (argc == 2) { - frontendName = std::string(argv[1]); - argv++; - argc--; - TMFE::Instance()->Msg(MINFO, __FUNCTION__, - "No equipment name provided; %s will be use", - DEFAULT_EQUIPMENT_NAME); - } else if (argc == 3) { - frontendName = std::string(argv[1]); - equipmentName = std::string(argv[2]); - argv += 2; - argc -= 2; - } - - auto front = ePowerSwitchFrontend(frontendName, equipmentName); - front.FeMain(argc, argv); -} - -ePowerSwitchFrontend::ePowerSwitchFrontend(std::string frontendName, - std::string equipmentName) { - FeSetName(frontendName.c_str()); - FeAddEquipment(new powerSwitch(equipmentName.c_str(), __FILE__)); -} \ No newline at end of file diff --git a/src/frontend/ePowerSwitchFrontend.h b/src/frontend/ePowerSwitchFrontend.h deleted file mode 100644 index 7649d92..0000000 --- a/src/frontend/ePowerSwitchFrontend.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef EPOWERSWITCH_FRONTEND_H -#define EPOWERSWITCH_FRONTEND_H - -#include "tmfe.h" - -class ePowerSwitchFrontend : public TMFrontend { - public: - /** - * @brief constructor - * - * @param frontendName name shown on Midas for the frontend - * @param equipmentName name shown on Midas for the equipment - */ - ePowerSwitchFrontend(std::string frontendName, std::string equipmentName); -}; - -#endif \ No newline at end of file diff --git a/src/frontend/ePowerSwitchFrontendConfig.h b/src/frontend/ePowerSwitchFrontendConfig.h deleted file mode 100644 index 8df2e9b..0000000 --- a/src/frontend/ePowerSwitchFrontendConfig.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef EPOWERSWITCH_CONFIG_H -#define EPOWERSWITCH_CONFIG_H - -#define DEFAULT_FRONTEND_NAME "ePowerSwitch" -#define DEFAULT_EQUIPMENT_NAME "powerswitch" - -#endif \ No newline at end of file -- 2.52.0 From e86db0f5718a5ce5061882bf1b92488f6ea51975 Mon Sep 17 00:00:00 2001 From: Hugo Jean Ponsin Date: Mon, 8 Jun 2026 09:24:13 +0200 Subject: [PATCH 22/22] renaming --- src/device/power_switch.cpp | 105 ++++++++++++++++++++++++ src/device/power_switch.h | 25 ++++++ src/device/power_switch_config.h | 28 +++++++ src/frontend/power_switch_scfe.cpp | 49 +++++++++++ src/frontend/power_switch_scfe.h | 17 ++++ src/frontend/power_switch_scfe_config.h | 7 ++ 6 files changed, 231 insertions(+) create mode 100644 src/device/power_switch.cpp create mode 100644 src/device/power_switch.h create mode 100644 src/device/power_switch_config.h create mode 100644 src/frontend/power_switch_scfe.cpp create mode 100644 src/frontend/power_switch_scfe.h create mode 100644 src/frontend/power_switch_scfe_config.h diff --git a/src/device/power_switch.cpp b/src/device/power_switch.cpp new file mode 100644 index 0000000..9fe129c --- /dev/null +++ b/src/device/power_switch.cpp @@ -0,0 +1,105 @@ +#include "power_switch.h" +#include "odbxx.h" +#include "power_switch_config.h" +#include "tmfe.h" +#include + +#include + +/** + * @brief Insert a integer value between two string + * @param str1 first string + * @param int value to insert + * @param str2 second string + * + * @return a new string instance + */ +std::string insert(const std::string *str1, int value, + const std::string *str2) { + return *str1 + std::to_string(value) + *str2; +} + +powerSwitch::powerSwitch(std::string equipmentName, + const char *equipmentFilename) + : TMFeEquipment(equipmentName.c_str(), equipmentFilename), + outletNumberRecord(mEpicsCa(EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX)) { + fEqConfReadOnlyWhenRunning = false; + + this->equipmentPath = std::string("/Equipment/") + equipmentName; +} + +void powerSwitch::HandlePeriodic() { + + updateOutletNumber(); + midas::odb o(this->equipmentPath); + + for (int i = 0; i < this->numberOfOutlet; i++) { + Outlet *outlet = &this->outlets.at(i); + + if (outlet->commandHasChange()) { + o[COMMAND_PATH.c_str()][i] = outlet->getCommand(); + } + o[READBACK_PATH.c_str()][i] = outlet->getState(); + } +} +TMFeResult powerSwitch::HandleInit(const std::vector &args) { + + midas::odb o = { + {SETTING_DIR.c_str(), {{EDITABLE_VARNAME.c_str(), COMMAND_VARNAME}}}}; + + o.connect(this->equipmentPath.c_str()); + + midas::odb to_watch(this->equipmentPath + SLASH + VARIABLES_DIR + SLASH + + COMMAND_VARNAME); + + to_watch.watch( + [&](midas::odb &arg) { this->sendCommand(arg.get_last_index()); }); + return TMFeOk(); +} +void powerSwitch::updateOutletNumber() { + int newNumberOfOutlet = 0; + + int returnCode = outletNumberRecord.get(&newNumberOfOutlet); + if (returnCode != CM_SUCCESS) { + fMfe->Msg(MERROR, __FUNCTION__, "Unable to read outlet record number"); + } + + if (this->numberOfOutlet < newNumberOfOutlet) + fMfe->Msg(MDEBUG, __FUNCTION__, + "Outlet number increasing, creating %d new outlet(s)", + newNumberOfOutlet - this->numberOfOutlet); + + for (int i = this->numberOfOutlet; i < newNumberOfOutlet; i++) { + std::string epicsSetRecordName; + { + static const std::string *str1 = &EPOWERSWITCH_OUTLET_SET_PREFIX; + static const std::string str2 = ""; + epicsSetRecordName = insert(str1, i + 1, &str2); + } + std::string epicsGetRecordName; + { + static const std::string *str1 = &EPOWERSWITCH_OUTLET_GET_PREFIX; + static const std::string str2 = ""; + epicsGetRecordName = insert(str1, i + 1, &str2); + } + this->outlets.emplace_back(i, epicsGetRecordName, epicsSetRecordName); + } + + if (this->numberOfOutlet > newNumberOfOutlet) + fMfe->Msg(MDEBUG, __FUNCTION__, + "Outlet number decreasing, destroying %d outlet(s)", + this->numberOfOutlet - newNumberOfOutlet); + + for (int i = newNumberOfOutlet; i < this->numberOfOutlet; i++) { + this->outlets.pop_back(); + } + + this->numberOfOutlet = newNumberOfOutlet; +} + +void powerSwitch::sendCommand(int index) { + midas::odb o(this->equipmentPath); + std::string command = o[COMMAND_PATH.c_str()][index]; + Outlet *outlet = &outlets.at(index); + outlet->setState(command); +} diff --git a/src/device/power_switch.h b/src/device/power_switch.h new file mode 100644 index 0000000..1acd9a4 --- /dev/null +++ b/src/device/power_switch.h @@ -0,0 +1,25 @@ +#ifndef POWER_SWITCH_H +#define POWER_SWITCH_H + +#include "../utils/outlet.h" +#include "tmfe.h" +#include + +class powerSwitch : public TMFeEquipment { + public: + powerSwitch(std::string equipmentName, const char *equipmentFilename); + void HandlePeriodic(); + TMFeResult HandleInit(const std::vector &args); + + private: + std::vector outlets; + mEpicsCa outletNumberRecord; + int numberOfOutlet; + std::string equipmentPath; + + void updateOutletNumber(); + + void sendCommand(int index); +}; + +#endif \ No newline at end of file diff --git a/src/device/power_switch_config.h b/src/device/power_switch_config.h new file mode 100644 index 0000000..4d9bfd5 --- /dev/null +++ b/src/device/power_switch_config.h @@ -0,0 +1,28 @@ +#ifndef POWER_SWITCH_CONFIG_H +#define POWER_SWITCH_CONFIG_H + +#include + +const std::string EPOWERSWITCH_OUTLETNUMBER_INFO_PREFIX = + "ePowerSwitch_config_maxOutlet"; + +const std::string VARIABLES_DIR = "Variables"; +const std::string SETTING_DIR = "Settings"; +const std::string COMMAND_VARNAME = "Command"; +const std::string READBACK_VARNAME = "Readback"; + +const std::string SLASH = "/"; + +const std::string EPOWERSWITCH_OUTLET_SET_PREFIX = "ePowerSwitch_set_outlet_"; +const std::string EPOWERSWITCH_OUTLET_GET_PREFIX = "ePowerSwitch_get_outlet_"; + +const std::string EDITABLE_VARNAME = std::string("Editable"); + +// ################################################## +// Paths names : do not modify +// ################################################## + +const std::string COMMAND_PATH = VARIABLES_DIR + SLASH + COMMAND_VARNAME; +const std::string READBACK_PATH = VARIABLES_DIR + SLASH + READBACK_VARNAME; + +#endif \ No newline at end of file diff --git a/src/frontend/power_switch_scfe.cpp b/src/frontend/power_switch_scfe.cpp new file mode 100644 index 0000000..a65d454 --- /dev/null +++ b/src/frontend/power_switch_scfe.cpp @@ -0,0 +1,49 @@ +#include "power_switch_scfe.h" +#include "../device/power_switch.h" +#include "power_switch_scfe_config.h" +#include "tmfe.h" + +int main(int argc, char *argv[]) { + + if (argv[0][0] == '.') { + TMFE::Instance()->Msg(MERROR, __FUNCTION__, + "Relative paths are strongly discouraged; " + "please use an absolute path."); + } + + std::string frontendName; + std::string equipmentName; + + if (argc == 1) { + frontendName = DEFAULT_FRONTEND_NAME; + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "No frontend name provided; %s will be used", + DEFAULT_FRONTEND_NAME); + equipmentName = DEFAULT_EQUIPMENT_NAME; + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "No equipment name provided; %s will be used", + DEFAULT_EQUIPMENT_NAME); + } + if (argc == 2) { + frontendName = std::string(argv[1]); + argv++; + argc--; + TMFE::Instance()->Msg(MINFO, __FUNCTION__, + "No equipment name provided; %s will be use", + DEFAULT_EQUIPMENT_NAME); + } else if (argc == 3) { + frontendName = std::string(argv[1]); + equipmentName = std::string(argv[2]); + argv += 2; + argc -= 2; + } + + auto front = powerSwitchSCFE(frontendName, equipmentName); + front.FeMain(argc, argv); +} + +powerSwitchSCFE::powerSwitchSCFE(std::string frontendName, + std::string equipmentName) { + FeSetName(frontendName.c_str()); + FeAddEquipment(new powerSwitch(equipmentName.c_str(), __FILE__)); +} \ No newline at end of file diff --git a/src/frontend/power_switch_scfe.h b/src/frontend/power_switch_scfe.h new file mode 100644 index 0000000..61f1dd6 --- /dev/null +++ b/src/frontend/power_switch_scfe.h @@ -0,0 +1,17 @@ +#ifndef POWER_SWITCH_SCFE_H +#define POWER_SWITCH_SCFE_H + +#include "tmfe.h" + +class powerSwitchSCFE : public TMFrontend { + public: + /** + * @brief constructor + * + * @param frontendName name shown on Midas for the frontend + * @param equipmentName name shown on Midas for the equipment + */ + powerSwitchSCFE(std::string frontendName, std::string equipmentName); +}; + +#endif \ No newline at end of file diff --git a/src/frontend/power_switch_scfe_config.h b/src/frontend/power_switch_scfe_config.h new file mode 100644 index 0000000..b963946 --- /dev/null +++ b/src/frontend/power_switch_scfe_config.h @@ -0,0 +1,7 @@ +#ifndef POWER_SWITCH_SCFE_CONFIG_H +#define POWER_SWITCH_SCFE_CONFIG_H + +#define DEFAULT_FRONTEND_NAME "powerSwitch" +#define DEFAULT_EQUIPMENT_NAME "powerswitch" + +#endif \ No newline at end of file -- 2.52.0