#include "../include/ePowerSwitchFront.h" #include "../include/ePowerSwitchConfig.h" #include "m_epics_ca.h" #include "tmfe.h" #include #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(); } int main(int argc, char *argv[]) { if (argv[0][0] == '.') { TMFE::Instance()->Msg(MERROR, __FUNCTION__, "Relative paths are strongly not recommended; " "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), outletNumberRecord(mEpicsCa( std::string_view(EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX), true)) { fEqConfReadConfigFromOdb = false; fEqConfPeriodMilliSec = 1000; fEqConfLogHistory = 1; fEqConfReadOnlyWhenRunning = false; fEqConfWriteEventsToOdb = true; this->numberOfOutlet = 0; } void ePowerSwitchEquipment::HandlePeriodic() { updateSocketNumber(); refreshAllSockets(); } void ePowerSwitchEquipment::refreshSocket(int socketId) { std::string varname = format("Socket ", socketId); int midasSocketState = 0; // default => turn off fOdbEqVariables->RI(varname.c_str(), &midasSocketState, true); if (midasSocketState != this->outletLastState.at(socketId)) { this->outletCommandRecords.at(socketId)->put(&midasSocketState); } this->outletLastState.at(socketId) = midasSocketState; } void ePowerSwitchEquipment::refreshAllSockets() { for (int i = 0; i < this->numberOfOutlet; i++) { refreshSocket(i); } } void ePowerSwitchEquipment::updateSocketNumber() { int epicsOutletNumber = 0; if (!outletNumberRecord.connected()) return; int returnCode = outletNumberRecord.get(&epicsOutletNumber); if (returnCode < 0) { printf("error\n"); return; } for (int i = this->numberOfOutlet; i < epicsOutletNumber; i++) { std::string epicsRecordName = format(EPOWERSWITCH_SOCKET_COMMAND_PREFIX, i); this->outletCommandRecords.push_back( new mEpicsCa(epicsRecordName.c_str(), true)); this->outletLastState.push_back(0); printf("new socket created\n"); } for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) { mEpicsCa *ptr = this->outletCommandRecords.back(); delete ptr; this->outletCommandRecords.pop_back(); this->outletLastState.pop_back(); printf("old socket destroyed\n"); } this->numberOfOutlet = epicsOutletNumber; } ePowerSwitchFrontend::ePowerSwitchFrontend(std::string frontendName, std::string equipmentName) { FeSetName(frontendName.c_str()); FeAddEquipment(new ePowerSwitchEquipment(equipmentName.c_str(), __FILE__)); }