1
0
Fork 0
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:
Steffen Vogel 2019-06-30 14:46:55 +02:00
parent ee3087bae6
commit 26500efb5b
9 changed files with 197 additions and 0 deletions

View file

@ -54,6 +54,7 @@
#cmakedefine WITH_API
#cmakedefine WITH_HOOKS
#cmakedefine WITH_CONFIG
#cmakedefine WITH_GRAPHVIZ
/* OS Headers */
#cmakedefine HAS_EVENTFD

View file

@ -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();

View file

@ -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 */

View file

@ -67,6 +67,7 @@ RUN pip install \
# Dependencies
RUN dnf -y install \
openssl-devel \
graphviz-devel \
protobuf-devel \
protobuf-c-devel \
libuuid-devel \

View file

@ -53,6 +53,7 @@ RUN dnf -y install \
# Dependencies
RUN dnf -y install \
openssl-devel \
graphviz-devel \
protobuf-devel \
protobuf-c-devel \
libuuid-devel \

View file

@ -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} \

View file

@ -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 \

View file

@ -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
View 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();
}
/** @} */