Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ test:python:
- pytest --verbose .
- black --line-length=90 --extend-exclude=".*(\\.pyi|_pb2.py)$" --check .
- flake8 --max-line-length=90 --extend-exclude="*.pyi,*_pb2.py" .
- mypy .
- mypy --explicit-package-bases villas/
image: ${DOCKER_IMAGE_DEV}:${DOCKER_TAG}
needs:
- job: "build:source: [fedora]"
Expand Down
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ pkg_check_modules(NANOMSG IMPORTED_TARGET nanomsg)
if(NOT NANOMSG_FOUND)
pkg_check_modules(NANOMSG IMPORTED_TARGET libnanomsg>=1.0.0)
endif()

pkg_check_modules(GRPC IMPORTED_TARGET grpc grpc++)
if (TARGET PkgConfig::GRPC)
set_property(TARGET PkgConfig::GRPC PROPERTY INTERFACE_COMPILE_OPTIONS "")
endif()

if (REDISPP_FOUND)
file(READ "${REDISPP_INCLUDEDIR}/sw/redis++/tls.h" CONTENTS)
Expand Down Expand Up @@ -180,6 +183,7 @@ cmake_dependent_option(WITH_SRC "Build executables"
cmake_dependent_option(WITH_TESTS "Run tests" "${WITH_DEFAULTS}" "TOPLEVEL_PROJECT" OFF)
cmake_dependent_option(WITH_TOOLS "Build auxilary tools" "${WITH_DEFAULTS}" "TOPLEVEL_PROJECT" OFF)
cmake_dependent_option(WITH_WEB "Build with internal webserver" "${WITH_DEFAULTS}" "LIBWEBSOCKETS_FOUND" OFF)
cmake_dependent_option(WITH_GRPC "Build with grpc api" "${WITH_DEFAULTS}" "GRPC_FOUND" OFF)

cmake_dependent_option(WITH_NODE_AMQP "Build with amqp node-type" "${WITH_DEFAULTS}" "RABBITMQ_C_FOUND" OFF)
cmake_dependent_option(WITH_NODE_CAN "Build with can node-type" "${WITH_DEFAULTS}" "" OFF)
Expand Down Expand Up @@ -290,6 +294,7 @@ add_feature_info(SRC WITH_SRC "Build execu
add_feature_info(TESTS WITH_TESTS "Run tests")
add_feature_info(TOOLS WITH_TOOLS "Build auxilary tools")
add_feature_info(WEB WITH_WEB "Build with internal webserver")
add_feature_info(GRPC_API WITH_GRPC "Build with gRPC API")

add_feature_info(NODE_AMQP WITH_NODE_AMQP "Build with amqp node-type")
add_feature_info(NODE_CAN WITH_NODE_CAN "Build with can node-type")
Expand Down
14 changes: 14 additions & 0 deletions etc/examples/nodes/gateway.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University
# SPDX-License-Identifier: Apache-2.0

nodes = {
gateway_node = {
type = "gateway"

format = "protobuf"
# API type
gateway_type = "gRPC"
# Address of remote server
address = "localhost:50051"
}
}
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@

opendssc = pkgs.callPackage (nixDir + "/opendssc.nix") { };
orchestra = pkgs.callPackage (nixDir + "/orchestra.nix") { };
grpc-server-reflection = pkgs.callPackage (nixDir + "/grpc_server_reflection.nix") { };
};
in
{
Expand Down
59 changes: 59 additions & 0 deletions include/villas/nodes/gateway.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* Node type for API gateway.
*
* Author: Jitpanu Maneeratpongsuk <jitpanu.maneeratpongsuk@rwth-aachen.de>
* SPDX-FileCopyrightText: 2025 Institute for Automation of Complex Power Systems, RWTH Aachen University
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <pthread.h>

#include <villas/format.hpp>
#include <villas/node.hpp>

namespace villas {
namespace node {

// Forward declarations
struct Sample;

class GatewayNode : public Node {
protected:
int parse(json_t *json) override;

int _read(struct Sample *smps[], unsigned cnt) override;
int _write(struct Sample *smps[], unsigned cnt) override;

public:
GatewayNode(const uuid_t &id = {}, const std::string &name = "");
enum ApiType { gRPC };

struct Direction {
Sample *sample;
pthread_cond_t cv;
pthread_mutex_t mutex;
char *buf;
size_t buflen;
size_t wbytes;
};

Direction read, write;
std::string address;
ApiType type;

Format::Ptr formatter;

int prepare() override;

int check() override;

int start() override;

int stop() override;

~GatewayNode();
};

} // namespace node
} // namespace villas
14 changes: 14 additions & 0 deletions lib/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ if(WITH_GRAPHVIZ)
list(APPEND LIBRARIES PkgConfig::CGRAPH PkgConfig::GVC)
endif()

if (WITH_GRPC)
find_path(REFLECTION_INCLUDE_DIR
NAMES grpc/reflection/v1alpha/reflection.pb.cc
)
if (REFLECTION_INCLUDE_DIR)
list(APPEND API_SRC
requests/gateway/grpc.cpp
${REFLECTION_INCLUDE_DIR}/grpc/reflection/v1alpha/reflection.pb.cc
${REFLECTION_INCLUDE_DIR}/grpc/reflection/v1alpha/reflection.grpc.pb.cc
)
list(APPEND LIBRARIES PkgConfig::PROTOBUF PkgConfig::GRPC)
endif()
endif()

add_library(api STATIC ${API_SRC})
target_include_directories(api PUBLIC ${INCLUDE_DIRS})
target_link_libraries(api PUBLIC ${LIBRARIES})
Loading