203 lines
6.6 KiB
C++
203 lines
6.6 KiB
C++
#include "ePowerSwitchEquipment.h"
|
|
#include "ePowerSwitchEquipmentConfig.h"
|
|
#include "tmfe.h"
|
|
#include <sstream>
|
|
|
|
/**
|
|
* @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<int>(
|
|
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, &str2);
|
|
}
|
|
std::string requestedVarname;
|
|
{
|
|
static const std::string str1 = "|-> ";
|
|
static const std::string str2 = " requested";
|
|
requestedVarname = insert(&str1, outletId, &str2);
|
|
}
|
|
std::string currentVarname;
|
|
{
|
|
static const std::string str1 = "\\-> ";
|
|
static const std::string str2 = " current";
|
|
currentVarname = insert(&str1, outletId, &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<mEpicsCa<std::string>>(
|
|
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<mEpicsCa<std::string>>(
|
|
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 requestedVarname;
|
|
std::string currentVarname;
|
|
{
|
|
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);
|
|
}
|
|
|
|
MVOdbError ovbError;
|
|
|
|
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;
|
|
}
|