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: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pkg_check_modules(CGRAPH IMPORTED_TARGET libcgraph>=2.30)
pkg_check_modules(GVC IMPORTED_TARGET libgvc>=2.30)
pkg_check_modules(LIBUSB IMPORTED_TARGET libusb-1.0>=1.0.23)
pkg_check_modules(NANOMSG IMPORTED_TARGET nanomsg)
pkg_check_modules(BZIP2 IMPORTED_TARGET bzip2)

if(NOT NANOMSG_FOUND)
pkg_check_modules(NANOMSG IMPORTED_TARGET libnanomsg>=1.0.0)
endif()
Expand Down
48 changes: 48 additions & 0 deletions etc/examples/hooks/create_chronics.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2014-2026 Institute for Automation of Complex Power Systems, RWTH Aachen University
# SPDX-License-Identifier: Apache-2.0

nodes = {

file_node = {
type = "file"
format = {
type = "csv"
separator = ","
delimiter = "\n"
skip_first_line = false
header = true
}
uris = ("./Load1.csv", "./SGen.csv")
uri = "test_uri"
in = {
read_mode = "all"
}

hooks = (
{
type = "create_chronics"
loads_dir = "./"
sgens_dir = "./"
grid = "./grid_file.json"
output = "./test_output"
round_decimals = 3
compress = true
}
)
},
dummy_node = {
type = "file"
format = "csv"
uri = "dummy"
out = {

}
}
}

paths = (
{
in = "file_node",
out = "dummy_node"
}
)
77 changes: 77 additions & 0 deletions include/villas/hooks/create_chronics.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* Create Chronics hook.
*
* Author: Ritesh Karki <ritesh.karki@rwth-aachen.de>
* SPDX-FileCopyrightText: 2014-2025 Institute for Automation of Complex Power Systems, RWTH Aachen University
* SPDX-License-Identifier: Apache-2.0
*/

#include <filesystem>
#include <unordered_map>
#include <vector>

#include <nlohmann/json.hpp>

#include <villas/hook.hpp>
#include <villas/sample.hpp>

namespace villas {
namespace node {

struct GridMapping {
std::unordered_map<int, int> load_bus;
std::unordered_map<int, int> sgen_bus;
};

struct ChronicsOptions {
std::filesystem::path loads_dir;
std::filesystem::path sgens_dir;
std::filesystem::path grid_path;
std::filesystem::path output_dir;
int round_decimals = 3;
bool compress = true;
bool negate_sgens = true;
float voltage = 20.0;

static ChronicsOptions from_json(const json_t &cfg);
};

class ChronicsHook : public Hook {

public:
using Hook::Hook;

void run();
void flush();
GridMapping load_grid();
void discover_files();
void process_load_files();
void process_sgen_files();
void process_samples_from_file(const std::string &filename,
const std::vector<Sample *> &samples);
void round_values();
void write_outputs();
void discover_files_from_node(struct file *f);

void prepare() override;
void start() override;
void stop() override;

private:
ChronicsOptions options;
GridMapping mapping;
std::vector<std::filesystem::path> load_files;
std::vector<std::filesystem::path> sgen_files;
std::vector<std::vector<double>> load_p_columns;
std::vector<std::vector<double>> load_q_columns;
std::vector<std::vector<double>> prod_p_columns;
std::vector<std::vector<double>> prod_q_columns;
std::vector<std::vector<double>> prod_v_columns;
std::vector<std::string> column_names;
std::string load_col_names;
std::string sgen_col_names;
bool done;
unsigned sgen_idx;
};

} // namespace node
} // namespace villas
22 changes: 22 additions & 0 deletions include/villas/nodes/file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

#pragma once

#include <cstddef>
#include <cstdio>
#include <map>
#include <string>
#include <vector>

#include <villas/format.hpp>
#include <villas/task.hpp>
Expand Down Expand Up @@ -57,6 +61,24 @@ struct file {
struct timespec epoch; // The epoch timestamp from the configuration.
struct timespec
offset; // An offset between the timestamp in the input file and the current time

std::vector<Sample *> samples;
size_t read_pos;

enum class ReadMode { RATE_BASED, READ_ALL } read_mode;
bool read;

// For multi-file support
std::vector<std::string> uri_templates;
std::vector<std::string> uris;

std::map<std::string, std::vector<Sample *>>
file_samples; // Map: filename --> filesamples
std::map<std::string, size_t>
file_read_pos; // Map: filename --> current read position in file
bool multi_file_mode;
size_t
total_files_size; //To calculate the total number of lines to be read across multiple files
};

char *file_print(NodeCompat *n);
Expand Down
2 changes: 2 additions & 0 deletions lib/hooks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(HOOK_SRC
skip_first.cpp
stats.cpp
ts.cpp
create_chronics.cpp
)

if(WITH_LUA)
Expand All @@ -49,3 +50,4 @@ endif()
add_library(hooks STATIC ${HOOK_SRC})
target_include_directories(hooks PUBLIC ${INCLUDE_DIRS})
target_link_libraries(hooks PUBLIC ${LIBRARIES})
target_link_libraries(hooks PUBLIC ${BZIP2_LIBRARIES})
Loading