mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
graph: add first version of graph output
This commit is contained in:
parent
ee3087bae6
commit
26500efb5b
9 changed files with 197 additions and 0 deletions
|
@ -54,6 +54,7 @@
|
|||
#cmakedefine WITH_API
|
||||
#cmakedefine WITH_HOOKS
|
||||
#cmakedefine WITH_CONFIG
|
||||
#cmakedefine WITH_GRAPHVIZ
|
||||
|
||||
/* OS Headers */
|
||||
#cmakedefine HAS_EVENTFD
|
||||
|
|
|
@ -23,6 +23,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <villas/node/config.h>
|
||||
|
||||
#ifdef WITH_GRAPHVIZ
|
||||
#include <graphviz/gvc.h>
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <villas/list.h>
|
||||
#include <villas/api.hpp>
|
||||
#include <villas/web.hpp>
|
||||
|
@ -108,6 +116,10 @@ public:
|
|||
void stopNodeTypes();
|
||||
void stopInterfaces();
|
||||
|
||||
#ifdef WITH_GRAPHVIZ
|
||||
graph_t * getGraph();
|
||||
#endif
|
||||
|
||||
/** Run periodic hooks of this super node. */
|
||||
int periodic();
|
||||
|
||||
|
|
|
@ -532,3 +532,20 @@ int SuperNode::periodic()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_GRAPHVIZ
|
||||
graph_t * SuperNode::getGraph()
|
||||
{
|
||||
/* Create a simple digraph */
|
||||
Agraph_t *g;
|
||||
Agnode_t *n, *m;
|
||||
Agedge_t *e;
|
||||
|
||||
g = agopen("g", Agdirected, 0);
|
||||
n = agnode(g, "n", 1);
|
||||
m = agnode(g, "m", 1);
|
||||
e = agedge(g, n, m, 0, 1);
|
||||
|
||||
return g;
|
||||
}
|
||||
#endif /* WITH_GRAPHVIZ */
|
||||
|
|
|
@ -67,6 +67,7 @@ RUN pip install \
|
|||
# Dependencies
|
||||
RUN dnf -y install \
|
||||
openssl-devel \
|
||||
graphviz-devel \
|
||||
protobuf-devel \
|
||||
protobuf-c-devel \
|
||||
libuuid-devel \
|
||||
|
|
|
@ -53,6 +53,7 @@ RUN dnf -y install \
|
|||
# Dependencies
|
||||
RUN dnf -y install \
|
||||
openssl-devel \
|
||||
graphviz-devel \
|
||||
protobuf-devel \
|
||||
protobuf-c-devel \
|
||||
libuuid-devel \
|
||||
|
|
|
@ -58,6 +58,7 @@ RUN apt-get update && \
|
|||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
libssl-dev:${ARCH} \
|
||||
libgraphviz-dev:${ARCH} \
|
||||
libprotobuf-dev:${ARCH} \
|
||||
libprotobuf-c-dev:${ARCH} \
|
||||
uuid-dev:${ARCH} \
|
||||
|
|
|
@ -52,6 +52,7 @@ RUN apt-get update && \
|
|||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
libssl-dev \
|
||||
libgraphviz-dev \
|
||||
libprotobuf-dev \
|
||||
libprotobuf-c-dev \
|
||||
uuid-dev \
|
||||
|
|
|
@ -51,6 +51,11 @@ target_link_libraries(villas-pipe PUBLIC villas Threads::Threads)
|
|||
add_executable(villas-signal villas-signal.cpp)
|
||||
target_link_libraries(villas-signal PUBLIC villas)
|
||||
|
||||
if(WITH_GRAPHVIZ)
|
||||
add_executable(villas-graph villas-graph.cpp)
|
||||
target_link_libraries(villas-graph PUBLIC villas)
|
||||
endif()
|
||||
|
||||
if(WITH_WEB)
|
||||
add_executable(villas-relay villas-relay.cpp)
|
||||
target_include_directories(villas-relay PRIVATE ${LIBWEBSOCKETS_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR})
|
||||
|
|
158
src/villas-graph.cpp
Normal file
158
src/villas-graph.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
/** Create a graph representation of the VILLASnode configuration file
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASnode
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @addtogroup tools Test and debug tools
|
||||
* @{
|
||||
*********************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <graphviz/types.h>
|
||||
#include <graphviz/gvcommon.h>
|
||||
|
||||
#include <villas/tool.hpp>
|
||||
#include <villas/utils.hpp>
|
||||
#include <villas/super_node.hpp>
|
||||
|
||||
using namespace villas;
|
||||
|
||||
struct GVC_s {
|
||||
GVCOMMON_t common;
|
||||
|
||||
char *config_path;
|
||||
boolean config_found;
|
||||
|
||||
/* gvParseArgs */
|
||||
char **input_filenames;
|
||||
};
|
||||
|
||||
namespace villas {
|
||||
namespace node {
|
||||
namespace tools {
|
||||
|
||||
class Graph : public Tool {
|
||||
|
||||
public:
|
||||
Graph(int argc, char *argv[]) :
|
||||
Tool(argc, argv, "graph", { SIGUSR1, SIGINT }),
|
||||
gvc(nullptr),
|
||||
graph(nullptr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = memory_init(DEFAULT_NR_HUGEPAGES);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize memory");
|
||||
|
||||
this->argv[0] = (char *) "neato"; /* Default layout engine */
|
||||
|
||||
gvc = gvContext();
|
||||
}
|
||||
|
||||
~Graph()
|
||||
{
|
||||
gvFreeContext(gvc);
|
||||
}
|
||||
|
||||
protected:
|
||||
GVC_t *gvc;
|
||||
graph_t *graph;
|
||||
|
||||
std::string configFilename;
|
||||
|
||||
void usage()
|
||||
{
|
||||
std::cout << "Usage: villas-graph [OPTIONS]" << std::endl
|
||||
<< "For OPTIONS see dot(1).";
|
||||
|
||||
printCopyright();
|
||||
}
|
||||
|
||||
void parse()
|
||||
{
|
||||
gvParseArgs(gvc, argc, argv);
|
||||
|
||||
std::list<std::string> filenames;
|
||||
int i;
|
||||
for (i = 0; gvc->input_filenames[i]; i++)
|
||||
filenames.emplace_back(gvc->input_filenames[i]);
|
||||
|
||||
if (i == 0)
|
||||
throw RuntimeError("No configuration file given!");
|
||||
|
||||
configFilename = filenames.front();
|
||||
}
|
||||
|
||||
virtual void handler(int signal, siginfo_t *siginfp, void *)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
switch (signal) {
|
||||
case SIGINT:
|
||||
/* If interrupted we try to produce a partial rendering before exiting */
|
||||
if (graph)
|
||||
gvRenderJobs(gvc, graph);
|
||||
break;
|
||||
|
||||
|
||||
case SIGUSR1:
|
||||
/* Note that we don't call gvFinalize() so that we don't start event-driven
|
||||
* devices like -Tgtk or -Txlib */
|
||||
exit(gvFreeContext(gvc));
|
||||
break;
|
||||
|
||||
default: { }
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int ret;
|
||||
|
||||
villas::node::SuperNode sn;
|
||||
|
||||
sn.parse(configFilename);
|
||||
sn.check();
|
||||
sn.prepare();
|
||||
|
||||
graph = sn.getGraph();
|
||||
|
||||
ret = gvLayoutJobs(gvc, graph); /* take layout engine from command line */
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return gvRenderJobs(gvc, graph);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tools
|
||||
} // namespace node
|
||||
} // namespace villas
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
node::tools::Graph t(argc, argv);
|
||||
|
||||
return t.run();
|
||||
}
|
||||
|
||||
/** @} */
|
Loading…
Add table
Reference in a new issue