#include "ePowerSwitchEquipment.h" #include "ePowerSwitchEquipmentConfig.h" #include "tmfe.h" #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 */ std::string format(std::string str, int value) { std::stringstream ss; ss << str; ss << value; return ss.str(); } ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName, const char *equipmentFileName) : TMFeEquipment(equipmentName.c_str(), equipmentFileName), 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 fEqConfLogHistory = 60; /// enable history system, generate one event per minutes fEqConfReadOnlyWhenRunning = false; /// allow to write values when running fEqConfWriteEventsToOdb = true; /// i don't know this->numberOfOutlet = 0; } void ePowerSwitchEquipment::HandlePeriodic() { updateSocketNumber(); refreshAllSockets(); } 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 midasRequestedSocketState = std::string("Off"); MVOdbError ovbError; int mepicscaReturnCode; fOdbEqVariables->RS(requestedVarname.c_str(), &midasRequestedSocketState, true, midasRequestedSocketState.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); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, "Couldn't get the value, skipping refreshing socket %d. " "Error code %d", socketId, mepicscaReturnCode); return; } if (epicsCurrentSocketState != midasRequestedSocketState) { mepicscaReturnCode = this->outletSetRecords.at(socketId)->put( &midasRequestedSocketState); if (mepicscaReturnCode != CM_SUCCESS) { fMfe->Msg(MERROR, __FUNCTION__, "Couldn't put the value, skipping refreshing socket %d. " "Error code %d", socketId, mepicscaReturnCode); return; } } fOdbEqVariables->WS(currentVarname.c_str(), epicsCurrentSocketState.c_str(), epicsCurrentSocketState.length() + 1, &ovbError); if (ovbError.fError) { fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); exit(EXIT_FAILURE); } } void ePowerSwitchEquipment::refreshAllSockets() { for (int i = 0; i < this->numberOfOutlet; i++) { refreshSocket(i); } } void ePowerSwitchEquipment::updateSocketNumber() { 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); return; } if (this->numberOfOutlet < epicsOutletNumber) fMfe->Msg(MDEBUG, __FUNCTION__, "Socket number increasing, creating %d new socket(s)", epicsOutletNumber - this->numberOfOutlet); for (int i = this->numberOfOutlet; i < epicsOutletNumber; i++) { std::string epicsSetRecordName = format(EPOWERSWITCH_SOCKET_SET_PREFIX, i); this->outletSetRecords.push_back( new mEpicsCa(epicsSetRecordName.c_str())); std::string epicsGetRecordName = format(EPOWERSWITCH_SOCKET_GET_PREFIX, i); this->outletGetRecords.push_back( new mEpicsCa(epicsGetRecordName.c_str())); } if (this->numberOfOutlet > epicsOutletNumber) fMfe->Msg(MDEBUG, __FUNCTION__, "Socket number decreasing, destroying %d socket(s)", 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"); std::string currentVarname = format("Socket ", i) + std::string(" current"); MVOdbError ovbError; fOdbEqVariables->Delete(requestedVarname.c_str(), &ovbError); if (ovbError.fError) fMfe->Msg(MERROR, __FUNCTION__, ovbError.fErrorString); 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; }