first ePowerSwitch verion
This commit is contained in:
+246
@@ -0,0 +1,246 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCaseColons: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowBreakBeforeNoexceptSpecifier: Never
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortCompoundRequirementOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakAdjacentStringLiterals: true
|
||||
BreakAfterAttributes: Leave
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: ".*"
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: "(Test)?$"
|
||||
IncludeIsMainSourceRegex: ""
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: false
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigits: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigits: 0
|
||||
Hex: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
KeepEmptyLinesAtEOF: false
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: DeriveLF
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: BinPack
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakScopeResolution: 500
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Leave
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
RemoveParentheses: Leave
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SkipMacroDefinitionBody: false
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeJsonColon: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterPlacementOperator: true
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
VerilogBreakBetweenInstancePorts: true
|
||||
WhitespaceSensitiveMacros:
|
||||
- BOOST_PP_STRINGIZE
|
||||
- CF_SWIFT_NAME
|
||||
- NS_SWIFT_NAME
|
||||
- PP_STRINGIZE
|
||||
- STRINGIZE
|
||||
---
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.vscode/
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
midas.log
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "submodule/mepicsca"]
|
||||
path = submodule/mepicsca
|
||||
url = git@gitea.psi.ch:lin-midas-drivers/mepicsca.git
|
||||
@@ -0,0 +1,98 @@
|
||||
cmake_minimum_required(VERSION 3.03)
|
||||
|
||||
project(ePowerSwitchFront VERSION 1.0)
|
||||
|
||||
add_subdirectory(submodule/mepicsca)
|
||||
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wformat=2
|
||||
-g
|
||||
-Wno-format-nonliteral
|
||||
-Wno-strict-aliasing
|
||||
-Wuninitialized
|
||||
-Wno-unused-function
|
||||
)
|
||||
|
||||
# Check if the required environment variables MIDASSYS and EPICSSYS are available
|
||||
if (NOT DEFINED ENV{MIDASSYS})
|
||||
message(SEND_ERROR "MIDASSYS environment variable not defined.")
|
||||
endif()
|
||||
if (NOT DEFINED ENV{EPICSSYS})
|
||||
message(SEND_ERROR "EPICSSYS environment variable not defined.")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(MIDASSYS $ENV{MIDASSYS})
|
||||
set(EPICSSYS $ENV{EPICSSYS})
|
||||
|
||||
# Select the correct EPICS library depending on the OS (currently Linus or Darwin are available)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES Linux)
|
||||
link_directories(${EPICSSYS}/lib/linux-x86_64)
|
||||
set(LIBS ${LIBS} -lpthread -lutil -lrt -lbsd -ldl)
|
||||
endif()
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES Darwin)
|
||||
link_directories(${EPICSSYS}/lib/darwin-aarch64)
|
||||
set(LIBS ${LIBS} -lutil -lca)
|
||||
endif()
|
||||
|
||||
set(LIBS
|
||||
${LIBS}
|
||||
${EPICSSYS}/lib/$ENV{EPICS_HOST_ARCH}/libca.so
|
||||
${EPICSSYS}/lib/$ENV{EPICS_HOST_ARCH}/libCom.so # For alarm.h
|
||||
$ENV{MIDASSYS}/lib/libmfe.a
|
||||
$ENV{MIDASSYS}/lib/libmidas.a
|
||||
$ENV{MIDASSYS}/lib/libmscb.a
|
||||
)
|
||||
|
||||
find_package(Midas REQUIRED)
|
||||
|
||||
add_executable(ePowerSwitchFront
|
||||
src/ePowerSwitchFront.cpp
|
||||
)
|
||||
|
||||
set_property(
|
||||
TARGET
|
||||
ePowerSwitchFront
|
||||
PROPERTY
|
||||
CXX_STANDARD 17
|
||||
)
|
||||
|
||||
|
||||
target_include_directories(
|
||||
ePowerSwitchFront
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PRIVATE
|
||||
$ENV{MIDASSYS}/drivers
|
||||
$ENV{MIDASSYS}/include
|
||||
|
||||
#$ENV{MIDASSYS}/drivers
|
||||
#$ENV{MIDASSYS}/include
|
||||
# This is redundant if MIDASSYS =/ Midas repo, but needed if MIDAS has been
|
||||
# installed in the repo directory, since the CMake file of MIDAS doesn't
|
||||
# copy the headers into $ENV{MIDASSYS}/include in the latter case.
|
||||
$ENV{MIDASSYS}/include/mscb
|
||||
${EPICSSYS}/include
|
||||
${EPICSSYS}/include/os/Linux
|
||||
${EPICSSYS}/include/os/Darwin
|
||||
${EPICSSYS}/include/compiler/gcc
|
||||
${EPICSSYS}/include/compiler/clang
|
||||
)
|
||||
|
||||
target_link_libraries(ePowerSwitchFront
|
||||
PRIVATE
|
||||
midas::mfe
|
||||
m_epics_ca
|
||||
${LIBS}
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
ePowerSwitchFront
|
||||
RUNTIME DESTINATION bin
|
||||
)
|
||||
|
||||
# Run the executable during the install process to register it in MIDAS
|
||||
# include(register_exe)
|
||||
# register_executable_once("${CMAKE_INSTALL_PREFIX}/bin/ePowerSwitchFront")
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef EPOWERSWITCH_CONFIG_H
|
||||
#define EPOWERSWITCH_CONFIG_H
|
||||
|
||||
#define EPOWERSWITCH_SOCKET_COMMAND_PREFIX "ePowerSwitch_command_outlet_"
|
||||
#define EPOWERSWITCH_SOCKETNUMBER_INFO_PREFIX "ePowerSwitch_config_maxOutlet"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef EPOWERSWITCH_FRONTEND_H
|
||||
#define EPOWERSWITCH_FRONTEND_H
|
||||
|
||||
#include "m_epics_ca.h"
|
||||
#include "tmfe.h"
|
||||
#include <vector>
|
||||
|
||||
class ePowerSwitchEquipment : public TMFeEquipment {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief contructor
|
||||
*
|
||||
* @param equipmentName name show on midas for the equipment
|
||||
* @param equipmentFileName file name for automatic tagged message
|
||||
*/
|
||||
ePowerSwitchEquipment(std::string equipmentName,
|
||||
const char *equipmentFileName);
|
||||
|
||||
/**
|
||||
* @brief call periodicly by midas
|
||||
*/
|
||||
void HandlePeriodic();
|
||||
|
||||
private:
|
||||
std::vector<mEpicsCa<int> *> outletCommandRecords;
|
||||
std::vector<int> outletLastState;
|
||||
mEpicsCa<int> 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 socket
|
||||
*/
|
||||
void refreshAllSockets();
|
||||
|
||||
/**
|
||||
* @brief detect and modify the current socket pool in case of change
|
||||
*/
|
||||
void updateSocketNumber();
|
||||
};
|
||||
|
||||
class ePowerSwitchFrontend : public TMFrontend {
|
||||
public:
|
||||
/**
|
||||
* @brief contructor
|
||||
*
|
||||
* @param frontendName name show on midas for the frontend
|
||||
* @param equipmentName name show on midas for the equipment
|
||||
*/
|
||||
ePowerSwitchFrontend(std::string frontendName, std::string equipmentName);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "ePowerSwitchFront.h"
|
||||
#include "ePowerSwitchConfig.h"
|
||||
#include "m_epics_ca.h"
|
||||
#include "tmfe.h"
|
||||
#include <format>
|
||||
#include <sstream>
|
||||
|
||||
/**
|
||||
* @brief local function, append an integer at the end of a string
|
||||
* @param str string prfix
|
||||
* @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[]) {
|
||||
std::string frontendName = "ePowerSwitch";
|
||||
std::string equipmentName = "powerswitch";
|
||||
|
||||
if (argc == 1) {
|
||||
frontendName = std::string(argv[1]);
|
||||
argv++;
|
||||
argc--;
|
||||
} else if (argc == 2) {
|
||||
frontendName = std::string(argv[1]);
|
||||
equipmentName = std::string(argv[2]);
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
|
||||
auto front = new ePowerSwitchFrontend(frontendName.c_str());
|
||||
front->FeMain(argc, argv);
|
||||
}
|
||||
|
||||
ePowerSwitchEquipment::ePowerSwitchEquipment(std::string equipmentName,
|
||||
const char *equipmentFileName)
|
||||
: TMFeEquipment(equipmentName, equipmentFileName),
|
||||
outletNumberRecord(
|
||||
mEpicsCa<int>(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);
|
||||
printf("send command : %d\n", 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<int>(epicsRecordName.c_str(), true));
|
||||
this->outletLastState.push_back(0);
|
||||
|
||||
printf("new socket created\n");
|
||||
}
|
||||
|
||||
for (int i = epicsOutletNumber; i < this->numberOfOutlet; i++) {
|
||||
mEpicsCa<int> *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(frontname.c_str());
|
||||
FeAddEquipment(new ePowerSwitchEquipment(equipmentName.c_str(), __FILE__));
|
||||
}
|
||||
Submodule
+1
Submodule submodule/mepicsca added at d9e17892ba
Reference in New Issue
Block a user