diff --git a/.gitignore b/.gitignore index 482ee7373b6394a0d546dc4bb5172639a48b1c33..31869c327c10768d31a16c5fd45d0d3b740084c8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ build/cmake_install.cmake build/libs/ build/spdlogConfigVersion.cmake build/spdlog.pc +build/compile_commands.json proto/*.h proto/*.cc libs/repasthpc/src/CMakeLists.txt diff --git a/.gitmodules b/.gitmodules index 310425b09913af144cbc29c7644918c28714a912..2561b76eccb153f3e54c58e1dc85851dd4b91447 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,10 @@ [submodule "libs/fbs-components"] path = libs/fbs-components url = https://git.rwth-aachen.de/acs/public/simulation/DistAIXFramework/fbs-components.git -[submodule "libs/villasnode"] - path = libs/villasnode - url = https://git.rwth-aachen.de/acs/public/villas/VILLASnode.git [submodule "libs/dbconnector"] path = libs/dbconnector url = https://git.rwth-aachen.de/acs/public/simulation/DistAIXFramework/dbconnector.git +[submodule "libs/villas-interface/villasnode"] + path = libs/villas-interface/villasnode + url = https://git.rwth-aachen.de/acs/public/villas/VILLASnode.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b49d92a712a70231df38d30c9fdb545dcfc369e..c817038bd106e788d07a0bf1c2438cf36d8f2d93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,14 +85,8 @@ endif() if(WITH_VILLAS) #add definition to use in the code add_definitions(-DWITH_VILLAS) - if(NANOMSG_FOUND) - list(APPEND LIBRARIES_DISTAIX villas ${NANOMSG_LIBRARIES}) - link_directories(${NANOMSG_LIBRARY_DIRS}) - else() - list(APPEND LIBRARIES_DISTAIX villas) - endif() - list(APPEND INCLUDE_DIRS_DISTAIX libs/villasnode/include) - + list(APPEND LIBRARIES_DISTAIX villas-interface) + list(APPEND INCLUDE_DIRS_DISTAIX libs/villa-interface/include) endif() add_executable(distaix ${SRC_LIST}) diff --git a/Dockerfile b/Dockerfile index d8354d3c0479810032631b242b06f46e081a73fc..cf7dfe56e75fce879a3ce8da4dfa984cdb7999ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,26 +19,16 @@ # along with this program. If not, see . ############################################################################# -FROM ubuntu:18.04 - -ARG GIT_REV=unknown -ARG GIT_BRANCH=unknown -ARG VERSION=unknown -ARG VARIANT=unknown - +FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive # Toolchain RUN apt-get update && apt-get install -y \ make libc6-dev dpkg-dev git wget unzip \ vim autoconf automake libtool \ - curl gcc-8 g++-8 cmake\ + curl gcc g++ cmake\ pkg-config openssl -# Redirect gcc to gcc-8 -RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 700 --slave /usr/bin/g++ g++ /usr/bin/g++-7 -RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8 -RUN update-alternatives --set gcc /usr/bin/gcc-8 # Dependencies of RepastHPC RUN apt-get update && apt-get install -y \ @@ -48,9 +38,9 @@ RUN apt-get update && apt-get install -y \ # Install Boost (Dependency of RepastHPC and DistAIX) RUN cd /tmp && mkdir boost && cd boost && \ - wget https://sourceforge.net/projects/boost/files/boost/1.69.0/boost_1_69_0.tar.gz && \ - tar xf boost_1_69_0.tar.gz && \ - cd boost_1_69_0 && \ + wget https://sourceforge.net/projects/boost/files/boost/1.79.0/boost_1_79_0.tar.gz && \ + tar xf boost_1_79_0.tar.gz && \ + cd boost_1_79_0 && \ ./bootstrap.sh --with-libraries=mpi,system,filesystem,serialization && \ echo "using mpi ;" >> user-config.jam && \ ./b2 --prefix=/usr --user-config=user-config.jam install || true && \ @@ -71,12 +61,12 @@ RUN cd /tmp && mkdir protobuf && cd protobuf && \ # Dependencies of DBconnector Library RUN apt-get update && apt-get install -y \ libuv1-dev libssl-dev libpq-dev \ - postgresql postgresql-contrib postgresql-server-dev-10 + postgresql postgresql-contrib postgresql-server-dev-12 # Install Cassandra cpp driver (Dependency of DBConnector Library) RUN cd /tmp && mkdir cass && cd cass && \ git clone https://github.com/datastax/cpp-driver.git . && \ - git checkout 2.10.0 && \ + git checkout 2.16.2 && \ mkdir build && cd build && \ cmake .. && make -j$(nproc) && make install && \ ldconfig && \ @@ -90,25 +80,27 @@ RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \ libconfig-dev libnl-3-dev libnl-route-3-dev \ libmosquitto-dev uuid-dev libuuid1 \ - libjansson-dev + libjansson-dev libwebsockets-dev \ + nanomsg-utils libnanomsg-dev + # Install libwebsockets version 3.0 (VILLASnode Dependency) -RUN cd /tmp && mkdir libwebsockets && cd libwebsockets && \ - git clone https://github.com/warmcat/libwebsockets . && \ - git checkout v3.0-stable && \ - mkdir build && cd build && \ - cmake .. && make -j$(nproc) && make install && \ - ldconfig && \ - rm -rf /tmp/* +#RUN cd /tmp && mkdir libwebsockets && cd libwebsockets && \ +# git clone https://github.com/warmcat/libwebsockets . && \ +# git checkout v3.0-stable && \ +# mkdir build && cd build && \ +# cmake .. && make -j$(nproc) && make install && \ +# ldconfig && \ +# rm -rf /tmp/* # Install nanomsg version 1.1.5 (VILLASnode and DistAIX dependency) -RUN cd /tmp && mkdir nanomsg && cd nanomsg && \ - wget -q https://github.com/nanomsg/nanomsg/archive/1.1.5.tar.gz && \ - tar -xzf 1.1.5.tar.gz && \ - cd nanomsg-1.1.5 && mkdir build && cd build && \ - cmake .. && cmake --build . --target install && \ - ldconfig && \ - rm -rf /tmp/* +#RUN cd /tmp && mkdir nanomsg && cd nanomsg && \ +# wget -q https://github.com/nanomsg/nanomsg/archive/1.1.5.tar.gz && \ +# tar -xzf 1.1.5.tar.gz && \ +# cd nanomsg-1.1.5 && mkdir build && cd build && \ +# cmake .. && cmake --build . --target install && \ +# ldconfig && \ +# rm -rf /tmp/* # Build & Install fmtlib RUN cd /tmp && \ @@ -138,10 +130,6 @@ LABEL \ org.label-schema.schema-version="1.0" \ org.label-schema.name="DistAIX" \ org.label-schema.license="GPL-3.0" \ - org.label-schema.vcs-ref="$GIT_REV" \ - org.label-schema.vcs-branch="$GIT_BRANCH" \ - org.label-schema.version="$VERSION" \ - org.label-schema.variant="$VARIANT" \ org.label-schema.vendor="Institute for Automation of Complex Power Systems, RWTH Aachen University" \ org.label-schema.description="An image containing all build-time dependencies for DistAIX based on Ubuntu" \ org.label-schema.vcs-url="https://git.rwth-aachen.de/acs/public/simulation/DistAIXFramework/distaix" \ diff --git a/include/agents/agent.h b/include/agents/agent.h index 7c9603f66b9e86f621be894f81e6a12969a2c7aa..b48de67934c10c8133e0abcdd11e4c31d2d9dbbd 100644 --- a/include/agents/agent.h +++ b/include/agents/agent.h @@ -138,9 +138,6 @@ public: bool outgoing_is_empty(); std::list get_outgoing_queue(); - /*Method to disconnect villas node*/ - int villas_interface_disconnect(); - /* Method to advance a simulation step */ virtual void step(); // virtual function, to be re-implemented in all derived agent classes diff --git a/include/agents/directoryfacilitator_agent.h b/include/agents/directoryfacilitator_agent.h index b3d382aa05269467d5594a13a17b26e54b413f88..49cdc675af8d81b4ed975f9e779c7cae253989d5 100644 --- a/include/agents/directoryfacilitator_agent.h +++ b/include/agents/directoryfacilitator_agent.h @@ -35,10 +35,9 @@ public: int &_behavior_type, int &_model_type, std::string &_subtype, - struct data_props _d_props, - villas_node_config *_villas_config + struct data_props _d_props ); - ~Directoryfacilitator_agent() override; + ~Directoryfacilitator_agent() override = default; void set_model_creator(Model_creator * _mc); void set_components_at_nodes(std::vector>> &_components_at_nodes); diff --git a/include/agents/msgrouter_agent.h b/include/agents/msgrouter_agent.h index 08c2a502bc7e82069bda7d305fb24e712664c150..c412c3c118421fc5ddf26fec6aa079c49b1aece4 100644 --- a/include/agents/msgrouter_agent.h +++ b/include/agents/msgrouter_agent.h @@ -37,7 +37,6 @@ public: int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, bool &_use_commdata ); ~Messagerouter_agent () override; diff --git a/include/agents/node_agent.h b/include/agents/node_agent.h index 5dd3db03f5a57cc6d83ec650967abd7e6d3a7b7d..f292d3741c0ec5727b18f988fc6be919b129afa1 100644 --- a/include/agents/node_agent.h +++ b/include/agents/node_agent.h @@ -36,11 +36,10 @@ public: int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, int _ifht_id, bool _ict_connected ); - ~Node_agent() override; + ~Node_agent() override = default; void step() override; diff --git a/include/agents/prosumer_agent.h b/include/agents/prosumer_agent.h index b7b2e7fabeae5e8dfaed4108c04310358b6d9ba6..b98c15e5f13afcf6df8be5de87171e63c107b5c5 100644 --- a/include/agents/prosumer_agent.h +++ b/include/agents/prosumer_agent.h @@ -34,7 +34,6 @@ public: Profile* profiles, std::string &interpolation_type, struct data_props _d_props, - villas_node_config *_villas_config, Prosumer_data * _prosumer_data ); ~Prosumer_agent() override; diff --git a/include/agents/slack_agent.h b/include/agents/slack_agent.h index 3a2921540a059e93c6d25ac83c85e03faa79e655..145f536c39ffabd85a81ca3bed187865a19913f4 100644 --- a/include/agents/slack_agent.h +++ b/include/agents/slack_agent.h @@ -36,7 +36,6 @@ public: int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, bool _ict_connected, bool _realtime = false ); @@ -50,11 +49,10 @@ public: int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, bool _ict_connected, bool _realtime = false ); - ~Slack_agent() override; + ~Slack_agent() override = default; void step() override; void calculate() override; diff --git a/include/agents/transformer_agent.h b/include/agents/transformer_agent.h index d88a3cb9010668f35d6d20918632d7f20e51eb38..5e1c0852f68bdf6a2bcfea418c5fc710e31fbfe1 100644 --- a/include/agents/transformer_agent.h +++ b/include/agents/transformer_agent.h @@ -39,7 +39,6 @@ public: int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, double _Vnom1, double _Vnom2, double R, diff --git a/include/behavior/agent_behavior.h b/include/behavior/agent_behavior.h index 6a1325c96d0b369c7f68adba7790b9d141a25b5c..26ea4ac4794532da9b67bbf120e6f7a7de02b1d8 100644 --- a/include/behavior/agent_behavior.h +++ b/include/behavior/agent_behavior.h @@ -22,15 +22,12 @@ #include "behavior/behavior_io.h" #include "agents/agent_datastructs.h" #include "behavior/agent_message.h" -#include "villas_interface/villas_message.h" - - +#ifdef WITH_VILLAS + #include "villas_interface.h" +#endif -//forward declaration -struct villas_node_config; -class Villas_interface; -#undef V //added because otherwise model_data.V cannot be accessed (V is defined in villas/utils.h) +//#undef V //added because otherwise model_data.V cannot be accessed (V is defined in villas/utils.h) /*! \brief Abstract base class for agent behavior * @@ -62,10 +59,6 @@ public: unsigned int get_msg_received(); unsigned int get_msg_sent(); - /*Methods related to villas interface*/ - int init_villas_interface(villas_node_config *_villas_config, std::vector &meta); - int destroy_villas_interface(); - protected: /* message processing */ void send_message(Agent_message &msg); @@ -83,7 +76,12 @@ protected: unsigned int msg_received; //!< number of received messages unsigned int msg_sent; //!< number of sent messages +#ifdef WITH_VILLAS Villas_interface * villas_interface; //!< villas interface that can be used in agent behavior + int init_villas_interface(std::string custom_param_json_string); /*Instantiate villas interface class*/ + void send_villas_msg(Villas_message &msg); + +#endif }; #endif diff --git a/include/behavior/dpsim_cosim/dpsim_cosim_behavior.h b/include/behavior/dpsim_cosim/dpsim_cosim_behavior.h index adc634143c9439c70148d8fce3fbb90436394b37..d331c886bcb019c2903c9aa5acc767c7e9705ae4 100644 --- a/include/behavior/dpsim_cosim/dpsim_cosim_behavior.h +++ b/include/behavior/dpsim_cosim/dpsim_cosim_behavior.h @@ -14,40 +14,66 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DPSIM_COSIM_BEHAVIOR #define DPSIM_COSIM_BEHAVIOR #include "behavior/agent_behavior.h" #include "dpsim_cosim_message.h" -//forwad declarations -struct villas_node_config; - /*! \brief abstract base class for nanomsg test behavior * */ class Dpsim_cosim_behavior : public Agent_behavior { public: - Dpsim_cosim_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config); - virtual ~Dpsim_cosim_behavior() override; + Dpsim_cosim_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, struct data_props _d_props, bool _realtime, bool _sync); + ~Dpsim_cosim_behavior() override; + + int initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) override; + + void execute_agent_behavior() override; + + /*global init functions and variables*/ + static int global_init(std::string config_file_path, double stop_at_init, int rank); /*process-wide inits for behavior*/ + static int global_cleanup(); /*process-wide cleanup for behavior*/ + static double global_step(double process_stop_at, int slack_rank, int world_size); /*process-wide actions to happen during step() method of model*/ + static double stop_at; /*Process-wide value for this behavior (can change during execution of simulation)*/ + + std::complex get_new_voltage_values(std::complex ¤t, double &v_re_old, double &v_im_old, double current_tick); protected: /* message processing */ - void process_incoming_messages(); - - virtual void process_dpsim_cosim_msg(Dpsim_cosim_msg &msg) = 0; + //void process_incoming_messages(); - /* message sending functions */ - void send_villas_msg(Villas_message &msg); + /*synchronization with dpsim*/ + void synchronize_with_remote(); - struct villas_node_config * vnconfig; + /* message sending functions */ + void send_msg(Dpsim_cosim_msg message); + void receive_message(std::list *incoming_villas_messages); + int busy_receive_msg(std::list *incoming_villas_messages); /* endpoint creation */ - void create_endpoints(villas_node_config * _vnconfig, std::string agent_id); + //void create_endpoints(villas_node_config * _vnconfig, std::string agent_id); + std::string get_json_config_string(int agent_id); + + void report_to_superior_grid(Dpsim_cosim_msg message, std::list *incoming_villas_messages, double current_tick); unsigned int numOfSentMessages = 0; unsigned int numOfReceivedMessages = 0; + + int sender; + double step_size; + + bool first_step = true; + bool realtime; + bool sync; + + int timeout = 5000; // timeout for busy waiting in milliseconds }; -#endif //DPSIM_COSIM_BEHAVIOR \ No newline at end of file +#endif //DPSIM_COSIM_BEHAVIOR +#endif \ No newline at end of file diff --git a/include/behavior/dpsim_cosim/dpsim_cosim_message.h b/include/behavior/dpsim_cosim/dpsim_cosim_message.h index 4d5db1d0ecc2c0b34490cd72520639a36dc18802..ea1c369371478253fb7ef0a19002f2479ddb57a7 100644 --- a/include/behavior/dpsim_cosim/dpsim_cosim_message.h +++ b/include/behavior/dpsim_cosim/dpsim_cosim_message.h @@ -14,35 +14,22 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DPSIM_COSIM_MESSAGE #define DPSIM_COSIM_MESSAGE #include -#include "villas_interface/villas_message.h" - +#include "villas_message.h" class Dpsim_cosim_msg : public Villas_message { public: - Dpsim_cosim_msg(); - Dpsim_cosim_msg(Villas_message &msg); + Dpsim_cosim_msg(std::complex value); ~Dpsim_cosim_msg() override = default; - std::complex * value; - - static std::vector dpsim_cosim_message_meta; - static bool meta_initialized; - - void set_pointers(); - static void init_meta(); - - std::string get_message_output(); - -private: - void init_message(std::complex _value); }; -#endif // DPSIM_COSIM_MESSAGE \ No newline at end of file +#endif // DPSIM_COSIM_MESSAGE +#endif \ No newline at end of file diff --git a/include/behavior/dpsim_cosim/dpsim_cosim_slack_behavior.h b/include/behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.h similarity index 56% rename from include/behavior/dpsim_cosim/dpsim_cosim_slack_behavior.h rename to include/behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.h index fd6e2259082157ae393877a0835b4d51816bbac1..928ecebfc160fd761bd30e68d34fb5f17741522c 100644 --- a/include/behavior/dpsim_cosim/dpsim_cosim_slack_behavior.h +++ b/include/behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.h @@ -15,46 +15,38 @@ * along with this program. If not, see . *********************************************************************************/ -#ifndef DPSIM_COSIM_SLACK_BEHAVIOR -#define DPSIM_COSIM_SLACK_BEHAVIOR +#ifdef WITH_VILLAS +#ifndef SWARM_DPSIM_COSIM_SLACK_BEHAVIOR +#define SWARM_DPSIM_COSIM_SLACK_BEHAVIOR +#include "behavior/dpsim_cosim/dpsim_cosim_message.h" #include "behavior/dpsim_cosim/dpsim_cosim_behavior.h" +#include "behavior/swarmgrid/swarm_slack_behavior.h" -/*! \brief Class for nanomsg test slack behavior +/*! \brief Class for dpsim cosim with swarm behavior * */ -class Dpsim_cosim_slack_behavior : public Dpsim_cosim_behavior { +class Dpsim_cosim_swarm_behavior : public Swarm_slack_behavior{ public: - Dpsim_cosim_slack_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, struct data_props _d_props, - villas_node_config * _villas_config, bool _realtime, bool _sync); - ~Dpsim_cosim_slack_behavior()= default; + Dpsim_cosim_swarm_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, struct data_props _d_props, + Slack_data * _slack_data, bool _realtime, bool _sync); + + ~Dpsim_cosim_swarm_behavior(); + int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, boost::multi_array *components_file, boost::multi_array *subtypes_file, boost::multi_array *el_grid_file) override; - void execute_agent_behavior() override; - void report_to_superior_grid(Dpsim_cosim_msg message, std::list *incoming_villas_messages); - -private: - void receive_msg(); - void receive_message(std::list *incoming_villas_messages); - void synchronize_with_remote(); - void process_dpsim_cosim_msg(Dpsim_cosim_msg &msg) override; - - int busy_receive_msg(std::list *incoming_villas_messages); - void send_msg(Dpsim_cosim_msg message); + std::complex get_new_voltage_values(std::complex ¤t, double &v_re_old, double &v_im_old, double current_tick); - int sender; - double step_size; - - bool first_step = true; - bool realtime; - bool sync; +private: + Dpsim_cosim_behavior *dpsim_cosim; + struct data_props dprops_dpsim_cosim; - int timeout = 5000; // timeout for busy waiting in milliseconds }; -#endif // DPSIM_COSIM_SLACK_BEHAVIOR \ No newline at end of file +#endif // DPSIM_COSIM_SLACK_BEHAVIOR +#endif \ No newline at end of file diff --git a/include/behavior/dpsim_cosim/villas_mqtt_dpsim_cosim.json b/include/behavior/dpsim_cosim/villas_mqtt_dpsim_cosim.json new file mode 100644 index 0000000000000000000000000000000000000000..cd5df2a0e5c7eb76646c2f921d7f6149c360fcd6 --- /dev/null +++ b/include/behavior/dpsim_cosim/villas_mqtt_dpsim_cosim.json @@ -0,0 +1,49 @@ +{ + "hugepages": 0, + "logging": { + "level": "debug", + "file": "./runlog/villas_rank" + }, + "node" : { + "type": "mqtt", + "format": { + "type":"json" + }, + "host": "localhost", + "port": 1883, + "qos": 0, + "retain": false, + "keepalive": 5, + "ssl" : { + "enabled": false, + "insecure": true, + "cafile:": "", + "certfile": "", + "keyfile": "" + }, + "in": { + "subscribe": "placeholder", + "signals": [ + { + "name": "value_complex", + "unit": "value_complex of this message", + "type": "complex" + } + ], + "vectorize": 1, + "enabled": true + }, + "out": { + "publish": "placeholder", + "signals": [ + { + "name": "value_complex", + "unit": "value_complex of this message", + "type": "complex" + } + ], + "vectorize": 1, + "enabled": true + } + } +} \ No newline at end of file diff --git a/include/behavior/dpsim_cosim/villas_nanomsg_dpsim_cosim.json b/include/behavior/dpsim_cosim/villas_nanomsg_dpsim_cosim.json new file mode 100644 index 0000000000000000000000000000000000000000..f1de10aad1e1c117bcbe1b35c486cee3a1230844 --- /dev/null +++ b/include/behavior/dpsim_cosim/villas_nanomsg_dpsim_cosim.json @@ -0,0 +1,41 @@ +{ + "hugepages": 0, + "logging": { + "level": "debug", + "file": "./runlog/villas_rank" + }, + "node": { + "type": "nanomsg", + "format": { + "type": "json" + }, + "in": { + "endpoints": [ + "ipc:///tmp/test1.ipc" + ], + "signals": [ + { + "name": "value_complex", + "unit": "value_complex of this message", + "type": "complex" + } + ], + "vectorize": 1, + "enabled": true + }, + "out": { + "endpoints": [ + "ipc:///tmp/test1.ipc" + ], + "signals": [ + { + "name": "value_complex", + "unit": "value_complex of this message", + "type": "complex" + } + ], + "vectorize": 1, + "enabled": true + } + } +} \ No newline at end of file diff --git a/include/behavior/ensure/ensure_behavior.h b/include/behavior/ensure/ensure_behavior.h index cb749b4fd1a99c8e10c742ed6c934422da5e2027..86085745b5d31cbaea737f2792efb040ec5c6504 100644 --- a/include/behavior/ensure/ensure_behavior.h +++ b/include/behavior/ensure/ensure_behavior.h @@ -14,23 +14,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_ENSURE_BEHAVIOR_H #define DISTAIX_ENSURE_BEHAVIOR_H #include "behavior/agent_behavior.h" #include "behavior/ensure/ensure_message.h" -//forward declarations -struct villas_node_config; /*! \brief abstract base class for reference ENSURE behavior * */ class Ensure_behavior : public Agent_behavior { public: - Ensure_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config); - virtual ~Ensure_behavior() override; + Ensure_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props); + ~Ensure_behavior() override =default; + + static int global_init(std::string config_file_path, int rank); /*process-wide inits for behavior*/ + static int global_cleanup(); /*process-wide cleanup for behavior*/ protected: int initialize_agent_behavior(std::vector>> * components_at_nodes, @@ -42,12 +42,8 @@ protected: /* message processing */ void handshake(); void process_incoming_messages(); - virtual void process_ensure_msg(Ensure_msg &msg) = 0; - - /* message sending functions */ - void send_villas_msg(Villas_message &msg); - - struct villas_node_config * vnconfig; + virtual void process_ensure_msg(Villas_message &msg) = 0; }; #endif //DISTAIX_ENSURE_BEHAVIOR_H +#endif diff --git a/include/behavior/ensure/ensure_knowledge.h b/include/behavior/ensure/ensure_knowledge.h index d31ded66b9225fae81d21ad9f43559f43e2716f7..07053d9767b927a9ba865c4912d3af6f7bfc8e35 100644 --- a/include/behavior/ensure/ensure_knowledge.h +++ b/include/behavior/ensure/ensure_knowledge.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef ENSURE_KNOWLEDGE #define ENSURE_KNOWLEDGE @@ -78,3 +78,4 @@ public: }; #endif // ENSURE_KNOWLEDGE +#endif diff --git a/include/behavior/ensure/ensure_message.h b/include/behavior/ensure/ensure_message.h index d32d23a9409eddc646cfc2b274167bef8127c4b0..2923bf93fcfb1346be480ccdceebd28d2549052e 100644 --- a/include/behavior/ensure/ensure_message.h +++ b/include/behavior/ensure/ensure_message.h @@ -14,53 +14,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_ENSURE_MESSAGE_H #define DISTAIX_ENSURE_MESSAGE_H -#include "villas_interface/villas_message.h" -/*! \brief Struct for storing ensure test data - * */ - -#define ENSURE_MESSAGE_LENGTH 6 - - +#include "villas_message.h" class Ensure_msg : public Villas_message { public: - Ensure_msg(); - - Ensure_msg(Villas_message &msg); - - Ensure_msg(int _performative, int _agent_id); - + Ensure_msg(int64_t performative, int64_t agent_id, double P, double Q, int64_t n, double v, double v2, double SOC, bool connected, int64_t t_connected); ~Ensure_msg() override = default; - - //pointers to elements - int64_t *performative; //!< type of communicative act - int64_t *agent_id; //!< identity of the agent - double *P; //!< setpoint for active power - double *Q; //!< setpoint for reactive power - int64_t *n; //!< set point for tap position - double *v; //!< voltage measurement value - double *v2; //!< second voltage measurement (for transformer) - double *SOC; //!< SOC measurement - bool *connected; //!< connection status - int64_t *t_connected; //!< time until disconnection in seconds - - static std::vector ensure_msg_meta; - static bool meta_initialized; - - void set_pointers(); - - static void init_meta(); - - std::string get_message_output(); - -private: - void init_message(int _performative, int _agent_id, double _P, - double _Q, int _n, double _v, double _v2, double _SOC, bool _conn, int _t_conn); }; #endif //DISTAIX_ENSURE_MESSAGE_H +#endif diff --git a/include/behavior/ensure/ensure_prosumer_behavior.h b/include/behavior/ensure/ensure_prosumer_behavior.h index cc75fb17dc932e7d81a77e9a8d9a954433358f99..2f97085ee8645419f583f2abccce7110b78d0b9a 100644 --- a/include/behavior/ensure/ensure_prosumer_behavior.h +++ b/include/behavior/ensure/ensure_prosumer_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_ENSURE_PROSUMER_BEHAVIOR_H #define DISTAIX_ENSURE_PROSUMER_BEHAVIOR_H @@ -26,13 +26,13 @@ class Ensure_prosumer_behavior : public Ensure_behavior { public: Ensure_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Prosumer_data * _prosumer_data); + Prosumer_data * _prosumer_data); ~Ensure_prosumer_behavior()=default; void execute_agent_behavior() override; protected: - void process_ensure_msg(Ensure_msg &msg) override; + void process_ensure_msg(Villas_message &msg) override; private: void publish_voltage_measurement(); @@ -46,3 +46,4 @@ private: #endif //DISTAIX_ENSURE_PROSUMER_BEHAVIOR_H +#endif \ No newline at end of file diff --git a/include/behavior/ensure/ensure_slack_behavior.h b/include/behavior/ensure/ensure_slack_behavior.h index c617459fb0a4387162499fdd2d6bf75cb333f00e..467ce3afcbbfc61450ca64604178c5713c1b93fd 100644 --- a/include/behavior/ensure/ensure_slack_behavior.h +++ b/include/behavior/ensure/ensure_slack_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_ENSURE_SLACK_BEHAVIOR_H #define DISTAIX_ENSURE_SLACK_BEHAVIOR_H @@ -26,13 +26,13 @@ class Ensure_slack_behavior : public Ensure_behavior { public: Ensure_slack_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, - struct data_props _d_props, villas_node_config * _villas_config, Slack_data * _slack_data); + struct data_props _d_props, Slack_data * _slack_data); ~Ensure_slack_behavior()=default; void execute_agent_behavior() override; protected: - void process_ensure_msg(Ensure_msg &msg) override; + void process_ensure_msg(Villas_message &msg) override; private: void send_measurement_message(); @@ -42,3 +42,4 @@ private: #endif //DISTAIX_ENSURE_SLACK_BEHAVIOR_H +#endif \ No newline at end of file diff --git a/include/behavior/ensure/ensure_substation_behavior.h b/include/behavior/ensure/ensure_substation_behavior.h index b2e4c0d548a6bf525ccadc6c735ce1fa7a8061db..67270493b34697233aeea62b0050534470439d09 100644 --- a/include/behavior/ensure/ensure_substation_behavior.h +++ b/include/behavior/ensure/ensure_substation_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_ENSURE_SUBSTATION_BEHAVIOR_H #define DISTAIX_ENSURE_SUBSTATION_BEHAVIOR_H @@ -26,13 +26,13 @@ class Ensure_substation_behavior : public Ensure_behavior { public: Ensure_substation_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Substation_data * _substation_data); + Substation_data * _substation_data); ~Ensure_substation_behavior()= default; void execute_agent_behavior() override; protected: - void process_ensure_msg(Ensure_msg &msg) override; + void process_ensure_msg(Villas_message &msg) override; private: void apply_control_values(); @@ -43,3 +43,4 @@ private: }; #endif //DISTAIX_ENSURE_SUBSTATION_BEHAVIOR_H +#endif diff --git a/include/behavior/ensure/villas_mqtt_ensure.json b/include/behavior/ensure/villas_mqtt_ensure.json new file mode 100644 index 0000000000000000000000000000000000000000..9100874e2cbbbfdbff95d0dabd472565fb515d79 --- /dev/null +++ b/include/behavior/ensure/villas_mqtt_ensure.json @@ -0,0 +1,139 @@ +{ + "hugepages": 0, + "logging": { + "level": "debug", + "file": "./runlog/villas_rank" + }, + "node": { + "type": "mqtt", + "format": { + "type": "json" + }, + "host": "localhost", + "port": 1883, + "qos": 0, + "retain": false, + "keepalive": 5, + "ssl": { + "enabled": false, + "insecure": true, + "cafile:": "", + "certfile": "", + "keyfile": "" + }, + "in": { + "subscribe": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "agent_id", + "unit": "id of agent involved in this message", + "type": "integer" + }, + { + "name": "P", + "unit": "W", + "type": "float" + }, + { + "name": "Q", + "unit": "var", + "type": "float" + }, + { + "name": "n", + "unit": "tap position", + "type": "integer" + }, + { + "name": "v", + "unit": "V", + "type": "float" + }, + { + "name": "v2", + "unit": "V", + "type": "float" + }, + { + "name": "soc", + "unit": "state of charge", + "type": "float" + }, + { + "name": "connected", + "unit": "boolean", + "type": "boolean" + }, + { + "name": "t_connected", + "unit": "s", + "type": "integer" + } + ], + "vectorize": 1, + "enabled": true + }, + "out": { + "publish": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "agent_id", + "unit": "id of agent involved in this message", + "type": "integer" + }, + { + "name": "P", + "unit": "W", + "type": "float" + }, + { + "name": "Q", + "unit": "var", + "type": "float" + }, + { + "name": "n", + "unit": "tap position", + "type": "integer" + }, + { + "name": "v", + "unit": "V", + "type": "float" + }, + { + "name": "v2", + "unit": "V", + "type": "float" + }, + { + "name": "soc", + "unit": "state of charge", + "type": "float" + }, + { + "name": "connected", + "unit": "boolean", + "type": "boolean" + }, + { + "name": "t_connected", + "unit": "s", + "type": "integer" + } + ], + "vectorize": 1, + "enabled": true + } + } +} \ No newline at end of file diff --git a/include/behavior/mqtt_highload/mqtt_highload_behavior.h b/include/behavior/mqtt_highload/mqtt_highload_behavior.h index d6fe77e647cec788e8bdc6917b8468cd362742ef..0fc86bfc68f44eae8bb7639c36823357d711d4f1 100644 --- a/include/behavior/mqtt_highload/mqtt_highload_behavior.h +++ b/include/behavior/mqtt_highload/mqtt_highload_behavior.h @@ -14,43 +14,30 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_HIGHLOAD_BEHAVIOR #define MQTT_HIGHLOAD_BEHAVIOR #include "behavior/agent_behavior.h" #include "behavior/mqtt_highload/mqtt_highload_message.h" -//forward declarations -struct villas_node_config; /*! \brief abstract base class for high load mqtt behavior * */ class Mqtt_highload_behavior : public Agent_behavior { public: - Mqtt_highload_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config); - virtual ~Mqtt_highload_behavior() override; + Mqtt_highload_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props); + ~Mqtt_highload_behavior() override =default; + + static int global_init(std::string config_file_path, int rank); /*process-wide inits for behavior*/ + static int global_cleanup(); /*process-wide cleanup for behavior*/ - int initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file) override; protected: /* message processing */ void process_incoming_messages(); - virtual void process_mqtt_highload_msg(Mqtt_highload_msg &msg) = 0; - - /* message sending functions */ - void send_villas_msg(Villas_message &msg); - - /*connection parameters*/ - virtual void set_connection_params(std::vector>> * components_at_nodes) = 0; - - - struct villas_node_config * vnconfig; + virtual void process_mqtt_highload_msg(Villas_message &msg) = 0; }; #endif //MQTT_HIGHLOAD_BEHAVIOR +#endif diff --git a/include/behavior/mqtt_highload/mqtt_highload_message.h b/include/behavior/mqtt_highload/mqtt_highload_message.h index 97b1304aba74c81aa1f8673ae5712af904277de7..a50522af95f93d888b9b4e0d6ed97ace900d5701 100644 --- a/include/behavior/mqtt_highload/mqtt_highload_message.h +++ b/include/behavior/mqtt_highload/mqtt_highload_message.h @@ -14,52 +14,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_HIGHLOAD_MESSAGE #define MQTT_HIGHLOAD_MESSAGE -#include "villas_interface/villas_message.h" -/*! \brief Struct for storing mqtt message data - * */ - -#define MQTT_HIGHLOAD_MESSAGE_LENGTH 10 - - +#include "villas_message.h" class Mqtt_highload_msg : public Villas_message { public: - Mqtt_highload_msg(); - Mqtt_highload_msg(Villas_message &msg); - Mqtt_highload_msg( int _performative, int _sender, int _receiver); + Mqtt_highload_msg(int64_t performative, int64_t sender, int64_t receiver, int64_t type1, double value1, int64_t type2, double value2, int64_t type3, double value3); ~Mqtt_highload_msg() override = default; - - //pointers to elements - int64_t * performative; //!< type of communicative act - int64_t * sender; //!< identity of the sender - int64_t * receiver; //!< identity of the receiver - int64_t * measurement_type_1; //!< type of measurement - double * measurement_value_1; //!< value of measurement - int64_t * measurement_type_2; //!< type of measurement - double * measurement_value_2; //!< value of measurement - int64_t * measurement_type_3; //!< type of measurement - double * measurement_value_3; //!< value of measurement - - static std::vector mqtt_highload_msg_meta; - static bool meta_initialized; - - void set_pointers(); - static void init_meta(); - - std::string get_message_output(); - -private: - void init_message(int _performative, int _sender, int _receiver, - int _measurement_type_1, double _measurement_value_1, - int _measurement_type_2, double _measurement_value_2, - int _measurement_type_3, double _measurement_value_3); - - }; -#endif //MQTT_HIGHLOAD_MESSAGE \ No newline at end of file +#endif //MQTT_HIGHLOAD_MESSAGE +#endif \ No newline at end of file diff --git a/include/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.h b/include/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.h index 40aa0c8522a88910cbf05f4147494a98dbbddc80..c04480f3f5c3aa15068db67e0c12eba1f80e1fb4 100644 --- a/include/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.h +++ b/include/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_HIGHLOAD_PROSUMER_BEHAVIOR #define MQTT_HIGHLOAD_PROSUMER_BEHAVIOR @@ -25,14 +25,18 @@ class Mqtt_highload_prosumer_behavior : public Mqtt_highload_behavior { public: Mqtt_highload_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Prosumer_data * _prosumer_data); + Prosumer_data * _prosumer_data); ~Mqtt_highload_prosumer_behavior()=default; + int initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) override; void execute_agent_behavior() override; protected: - void process_mqtt_highload_msg(Mqtt_highload_msg &msg) override; - void set_connection_params(std::vector>> * components_at_nodes) override; + void process_mqtt_highload_msg(Villas_message &msg) override; private: void publish_measurement_data(); @@ -43,3 +47,4 @@ private: }; #endif //MQTT_HIGHLOAD_PROSUMER_BEHAVIOR +#endif diff --git a/include/behavior/mqtt_highload/mqtt_highload_substation_behavior.h b/include/behavior/mqtt_highload/mqtt_highload_substation_behavior.h index bae24102b3c595e508a6017acf6567952e3a33de..c0d1891f8bd4346036eda1393731783b642c4dca 100644 --- a/include/behavior/mqtt_highload/mqtt_highload_substation_behavior.h +++ b/include/behavior/mqtt_highload/mqtt_highload_substation_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_HIGHLOAD_SUBSTATION_BEHAVIOR #define MQTT_HIGHLOAD_SUBSTATION_BEHAVIOR @@ -25,13 +25,18 @@ class Mqtt_highload_substation_behavior : public Mqtt_highload_behavior { public: Mqtt_highload_substation_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Substation_data * _substation_data); + Substation_data * _substation_data); ~Mqtt_highload_substation_behavior()= default; + int initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) override; + void execute_agent_behavior() override; protected: - void process_mqtt_highload_msg(Mqtt_highload_msg &msg) override; - void set_connection_params(std::vector>> * components_at_nodes) override; + void process_mqtt_highload_msg(Villas_message &msg) override; private: void apply_control_values(); @@ -42,3 +47,4 @@ private: }; #endif //MQTT_HIGHLOAD_SUBSTATION_BEHAVIOR +#endif diff --git a/include/behavior/mqtt_highload/villas_mqtt_highload.json b/include/behavior/mqtt_highload/villas_mqtt_highload.json new file mode 100644 index 0000000000000000000000000000000000000000..7710c049f6dd626f3d00410e684fd0a4c4f95202 --- /dev/null +++ b/include/behavior/mqtt_highload/villas_mqtt_highload.json @@ -0,0 +1,129 @@ +{ + "hugepages": 0, + "logging": { + "level": "debug", + "file": "./runlog/villas_rank" + }, + "node" : { + "type": "mqtt", + "format": { + "type":"json" + }, + "host": "localhost", + "port": 1883, + "qos": 0, + "retain": false, + "keepalive": 5, + "ssl" : { + "enabled": false, + "insecure": true, + "cafile:": "", + "certfile": "", + "keyfile": "" + }, + "in": { + "subscribe": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "sender", + "unit": "sender of this message", + "type": "integer" + }, + { + "name": "receiver", + "unit": "receiver of this message", + "type": "integer" + }, + { + "name": "measurement_type_1", + "unit": "measurement_type_1 of this message", + "type": "integer" + }, + { + "name": "measurement_value_1", + "unit": "measurement_value_1 of this message", + "type": "float" + }, + { + "name": "measurement_type_2", + "unit": "measurement_type_2 of this message", + "type": "integer" + }, + { + "name": "measurement_value_2", + "unit": "measurement_value_2 of this message", + "type": "float" + }, + { + "name": "measurement_type_3", + "unit": "measurement_type_3 of this message", + "type": "integer" + }, + { + "name": "measurement_value_3", + "unit": "measurement_value_3 of this message", + "type": "float" + } + ], + "vectorize": 1, + "enabled": true + }, + "out": { + "publish": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "sender", + "unit": "sender of this message", + "type": "integer" + }, + { + "name": "receiver", + "unit": "receiver of this message", + "type": "integer" + }, + { + "name": "measurement_type_1", + "unit": "measurement_type_1 of this message", + "type": "integer" + }, + { + "name": "measurement_value_1", + "unit": "measurement_value_1 of this message", + "type": "float" + }, + { + "name": "measurement_type_2", + "unit": "measurement_type_2 of this message", + "type": "integer" + }, + { + "name": "measurement_value_2", + "unit": "measurement_value_2 of this message", + "type": "float" + }, + { + "name": "measurement_type_3", + "unit": "measurement_type_3 of this message", + "type": "integer" + }, + { + "name": "measurement_value_3", + "unit": "measurement_value_3 of this message", + "type": "float" + } + ], + "vectorize": 1, + "enabled": true + } + } +} \ No newline at end of file diff --git a/include/behavior/mqtt_pingpong/mqtt_pingpong_behavior.h b/include/behavior/mqtt_pingpong/mqtt_pingpong_behavior.h index 1b67bbc29cd9618b539f0ec903d6e7140d33c79d..7b964175f0cdbb50706a59270ef9ce270f6feb72 100644 --- a/include/behavior/mqtt_pingpong/mqtt_pingpong_behavior.h +++ b/include/behavior/mqtt_pingpong/mqtt_pingpong_behavior.h @@ -14,23 +14,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_MQTT_PINGPONG_BEHAVIOR_H #define DISTAIX_MQTT_PINGPONG_BEHAVIOR_H #include "behavior/agent_behavior.h" #include "behavior/mqtt_pingpong/mqtt_pingpong_message.h" -//forward declarations -struct villas_node_config; /*! \brief abstract base class for MQTT pingpong test behavior * */ class Mqtt_pingpong_behavior : public Agent_behavior { public: - Mqtt_pingpong_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config); - virtual ~Mqtt_pingpong_behavior() override; + Mqtt_pingpong_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props); + ~Mqtt_pingpong_behavior() override =default; + + static int global_init(std::string config_file_path, int rank); /*process-wide inits for behavior*/ + static int global_cleanup(); /*process-wide cleanup for behavior*/ protected: int initialize_agent_behavior(std::vector>> * components_at_nodes, @@ -41,13 +41,11 @@ protected: /* message processing */ void process_incoming_messages(); - virtual void process_mqtt_pingpong_msg(Mqtt_pingpong_msg &msg) = 0; + virtual void process_mqtt_pingpong_msg(Villas_message &msg) = 0; /* message sending functions */ - void send_villas_msg(Villas_message &msg); void handshake(); - - struct villas_node_config * vnconfig; }; #endif //DISTAIX_MQTT_PINGPONG_BEHAVIOR_H +#endif \ No newline at end of file diff --git a/include/behavior/mqtt_pingpong/mqtt_pingpong_message.h b/include/behavior/mqtt_pingpong/mqtt_pingpong_message.h index d83ab390bf21f946555a20304e8b723a7b358892..b7a4779e69c644145c3be26dd1848da06c4ff748 100644 --- a/include/behavior/mqtt_pingpong/mqtt_pingpong_message.h +++ b/include/behavior/mqtt_pingpong/mqtt_pingpong_message.h @@ -14,49 +14,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_MQTT_PINGPONG_MESSAGE_H #define DISTAIX_MQTT_PINGPONG_MESSAGE_H -#include "villas_interface/villas_message.h" -/*! \brief Struct for storing ensure test data - * */ - -#define MQTT_PINGPONG_MESSAGE_LENGTH 6 - - +#include "villas_message.h" class Mqtt_pingpong_msg : public Villas_message { public: - - Mqtt_pingpong_msg(); - - Mqtt_pingpong_msg(Villas_message &msg); - - Mqtt_pingpong_msg(int _performative, int _agent_id); - + Mqtt_pingpong_msg(int64_t performative, int64_t agent_id, double P_ctrl, double Q_ctrl, int64_t n_ctrl, double v_meas); ~Mqtt_pingpong_msg() override = default; - - //pointers to elements - int64_t *performative; //!< type of communicative act - int64_t *agent_id; //!< identity of the agent - double *P_ctrl; //!< setpoint for active power - double *Q_ctrl; //!< setpoint for reactive power - int64_t *n_ctrl; //!< set point for tap position - double *v_meas; //!< voltage measurement value - - static std::vector mqtt_pingpong_msg_meta; - static bool meta_initialized; - - void set_pointers(); - - static void init_meta(); - - std::string get_message_output(); - -private: - void init_message(int _performative, int _agent_id, double _P_ctrl, - double _Q_ctrl, int _n_ctrl, double _v_meas); }; #endif //DISTAIX_MQTT_PINGPONG_MESSAGE_H +#endif diff --git a/include/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.h b/include/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.h index 5c4ffd027919e91237972549da387065cae00280..fac0f2b1ac3d7e94f3a7d52d71e63398a3bf25a5 100644 --- a/include/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.h +++ b/include/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_MQTT_PINGPONG_PROSUMER_BEHAVIOR_H #define DISTAIX_MQTT_PINGPONG_PROSUMER_BEHAVIOR_H @@ -25,13 +25,13 @@ class Mqtt_pingpong_prosumer_behavior : public Mqtt_pingpong_behavior { public: Mqtt_pingpong_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Prosumer_data * _prosumer_data); + Prosumer_data * _prosumer_data); ~Mqtt_pingpong_prosumer_behavior()=default; void execute_agent_behavior() override; protected: - void process_mqtt_pingpong_msg(Mqtt_pingpong_msg &msg) override; + void process_mqtt_pingpong_msg(Villas_message &msg) override; private: void publish_voltage_measurement(); @@ -43,3 +43,4 @@ private: #endif //DISTAIX_MQTT_PINGPONG_PROSUMER_BEHAVIOR_H +#endif diff --git a/include/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.h b/include/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.h index 4cf2be9357150807df4869603e57e48d1d013a95..d65bb2f43af79a2c355ad97b72eb1a430ce0a4cd 100644 --- a/include/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.h +++ b/include/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef DISTAIX_MQTT_PINGPONG_SUBSTATION_BEHAVIOR_H #define DISTAIX_MQTT_PINGPONG_SUBSTATION_BEHAVIOR_H @@ -25,13 +25,13 @@ class Mqtt_pingpong_substation_behavior : public Mqtt_pingpong_behavior { public: Mqtt_pingpong_substation_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Substation_data * _substation_data); + Substation_data * _substation_data); ~Mqtt_pingpong_substation_behavior()= default; void execute_agent_behavior() override; protected: - void process_mqtt_pingpong_msg(Mqtt_pingpong_msg &msg) override; + void process_mqtt_pingpong_msg(Villas_message &msg) override; private: void apply_control_values(); @@ -41,3 +41,4 @@ private: }; #endif //DISTAIX_MQTT_PINGPONG_SUBSTATION_BEHAVIOR_H +#endif diff --git a/include/behavior/mqtt_pingpong/villas_mqtt_pingpong.json b/include/behavior/mqtt_pingpong/villas_mqtt_pingpong.json new file mode 100644 index 0000000000000000000000000000000000000000..08c2b4c5411ce496b33e44e9d4b20fababf027f9 --- /dev/null +++ b/include/behavior/mqtt_pingpong/villas_mqtt_pingpong.json @@ -0,0 +1,99 @@ +{ + "hugepages": 0, + "logging": { + "level": "debug", + "file": "./runlog/villas_rank" + }, + "node" : { + "type": "mqtt", + "format": { + "type":"json" + }, + "host": "localhost", + "port": 1883, + "qos": 0, + "retain": false, + "keepalive": 5, + "ssl" : { + "enabled": false, + "insecure": true, + "cafile:": "", + "certfile": "", + "keyfile": "" + }, + "in": { + "subscribe": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "agent_id", + "unit": "id of agent involved in this message", + "type": "integer" + }, + { + "name": "P_ctrl", + "unit": "W", + "type": "float" + }, + { + "name": "Q_ctrl", + "unit": "var", + "type": "float" + }, + { + "name": "n_ctrl", + "unit": "tap pos", + "type": "integer" + }, + { + "name": "v_meas", + "unit": "V", + "type": "float" + } + ], + "vectorize": 1, + "enabled": true + }, + "out": { + "publish": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "agent_id", + "unit": "id of agent involved in this message", + "type": "integer" + }, + { + "name": "P_ctrl", + "unit": "W", + "type": "float" + }, + { + "name": "Q_ctrl", + "unit": "var", + "type": "float" + }, + { + "name": "n_ctrl", + "unit": "tap pos", + "type": "integer" + }, + { + "name": "v_meas", + "unit": "V", + "type": "float" + } + ], + "vectorize": 1, + "enabled": true + } + } +} \ No newline at end of file diff --git a/include/behavior/mqtt_reference/mqtt_message.h b/include/behavior/mqtt_reference/mqtt_message.h index 6bbfd65a58ab13e1b01f0532ecd42f88e9e11f2e..70081a63a0e3ddfe09d79e03ba501c66bcb49897 100644 --- a/include/behavior/mqtt_reference/mqtt_message.h +++ b/include/behavior/mqtt_reference/mqtt_message.h @@ -14,45 +14,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_MESSAGE #define MQTT_MESSAGE -#include "villas_interface/villas_message.h" -/*! \brief Struct for storing mqtt message data - * */ - -#define MQTT_REF_MESSAGE_LENGTH 6 - - +#include "villas_message.h" class Mqtt_ref_msg : public Villas_message { public: - Mqtt_ref_msg(); - Mqtt_ref_msg(Villas_message &msg); - Mqtt_ref_msg( int _performative, int _sender, int _receiver); + Mqtt_ref_msg(int64_t performative, int64_t sender, int64_t receiver, int64_t type, double value); ~Mqtt_ref_msg() override = default; - //pointers to elements - int64_t * performative; //!< type of communicative act - int64_t * sender; //!< identity of the sender - int64_t * receiver; //!< identity of the receiver - int64_t * measurement_type; //!< type of measurement - double * measurement_value; //!< value of measurement - - static std::vector mqtt_ref_msg_meta; - static bool meta_initialized; - - void set_pointers(); - static void init_meta(); - - std::string get_message_output(); - -private: - void init_message(int _performative, int _sender, int _receiver, int _measurement_type, double _measurement_value); - - }; -#endif //MQTT_MESSAGE \ No newline at end of file +#endif //MQTT_MESSAGE +#endif \ No newline at end of file diff --git a/include/behavior/mqtt_reference/mqtt_ref_behavior.h b/include/behavior/mqtt_reference/mqtt_ref_behavior.h index 22b0baca4343849c66dee1d70f50eecbda172913..26d1f1441fbc6146d3a83e74b630acaf3ddc01ed 100644 --- a/include/behavior/mqtt_reference/mqtt_ref_behavior.h +++ b/include/behavior/mqtt_reference/mqtt_ref_behavior.h @@ -14,43 +14,29 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_REF_BEHAVIOR #define MQTT_REF_BEHAVIOR #include "behavior/agent_behavior.h" #include "behavior/mqtt_reference/mqtt_message.h" -//forward declarations -struct villas_node_config; - /*! \brief abstract base class for reference mqtt behavior * */ class Mqtt_ref_behavior : public Agent_behavior { public: - Mqtt_ref_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config); - virtual ~Mqtt_ref_behavior() override; + Mqtt_ref_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props); + ~Mqtt_ref_behavior() override =default; + + static int global_init(std::string config_file_path, int rank); /*process-wide inits for behavior*/ + static int global_cleanup(); /*process-wide cleanup for behavior*/ - int initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file) override; protected: /* message processing */ void process_incoming_messages(); - virtual void process_mqtt_ref_msg(Mqtt_ref_msg &msg) = 0; - - /* message sending functions */ - void send_villas_msg(Villas_message &msg); - - /*connection parameters*/ - virtual void set_connection_params(std::vector>> * components_at_nodes) = 0; - - - struct villas_node_config * vnconfig; + virtual void process_mqtt_ref_msg(Villas_message &msg) = 0; }; #endif +#endif diff --git a/include/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.h b/include/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.h index 70522e9d117d7214b3efeae7512834278a3577d8..4e1602e35e7941ced7240bc7e18174c27344646c 100644 --- a/include/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.h +++ b/include/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_REF_PROSUMER_BEHAVIOR #define MQTT_REF_PROSUMER_BEHAVIOR @@ -25,14 +25,18 @@ class Mqtt_ref_prosumer_behavior : public Mqtt_ref_behavior { public: Mqtt_ref_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Prosumer_data * _prosumer_data); + Prosumer_data * _prosumer_data); ~Mqtt_ref_prosumer_behavior()=default; + int initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) override; void execute_agent_behavior() override; protected: - void process_mqtt_ref_msg(Mqtt_ref_msg &msg) override; - void set_connection_params(std::vector>> * components_at_nodes) override; + void process_mqtt_ref_msg(Villas_message &msg) override; private: void publish_voltage_measurement(); @@ -43,3 +47,4 @@ private: }; #endif //MQTT_REF_PROSUMER_BEHAVIOR +#endif diff --git a/include/behavior/mqtt_reference/mqtt_ref_substation_behavior.h b/include/behavior/mqtt_reference/mqtt_ref_substation_behavior.h index 2e0d45650ed0a6101cec00682e1a58028ec782ac..d579df375aa0009975f8c482edda827c61904dcc 100644 --- a/include/behavior/mqtt_reference/mqtt_ref_substation_behavior.h +++ b/include/behavior/mqtt_reference/mqtt_ref_substation_behavior.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #ifndef MQTT_REF_SUBSTATION_BEHAVIOR #define MQTT_REF_SUBSTATION_BEHAVIOR @@ -25,13 +25,18 @@ class Mqtt_ref_substation_behavior : public Mqtt_ref_behavior { public: Mqtt_ref_substation_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, struct data_props _d_props, - villas_node_config * _villas_config, Substation_data * _substation_data); + Substation_data * _substation_data); ~Mqtt_ref_substation_behavior()= default; + int initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) override; + void execute_agent_behavior() override; protected: - void process_mqtt_ref_msg(Mqtt_ref_msg &msg) override; - void set_connection_params(std::vector>> * components_at_nodes) override; + void process_mqtt_ref_msg(Villas_message &msg) override; private: void apply_control_values(); @@ -41,3 +46,4 @@ private: }; #endif //MQTT_REF_SUBSTATION_BEHAVIOR +#endif diff --git a/include/behavior/mqtt_reference/villas_mqtt_ref.json b/include/behavior/mqtt_reference/villas_mqtt_ref.json new file mode 100644 index 0000000000000000000000000000000000000000..5366e9d32889e6d9424843ad28a5a79692cbe103 --- /dev/null +++ b/include/behavior/mqtt_reference/villas_mqtt_ref.json @@ -0,0 +1,89 @@ +{ + "hugepages": 0, + "logging": { + "level": "debug", + "file": "./runlog/villas_rank" + }, + "node" : { + "type": "mqtt", + "format": { + "type":"json" + }, + "host": "localhost", + "port": 1883, + "qos": 0, + "retain": false, + "keepalive": 5, + "ssl" : { + "enabled": false, + "insecure": true, + "cafile:": "", + "certfile": "", + "keyfile": "" + }, + "in": { + "subscribe": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "sender", + "unit": "sender of this message", + "type": "integer" + }, + { + "name": "receiver", + "unit": "receiver of this message", + "type": "integer" + }, + { + "name": "measurement_type", + "unit": "measurement_type of this message", + "type": "integer" + }, + { + "name": "measurement_value", + "unit": "measurement_value of this message", + "type": "float" + } + ], + "vectorize": 1, + "enabled": true + }, + "out": { + "publish": "placeholder", + "signals": [ + { + "name": "performative", + "unit": "performative of this message", + "type": "integer" + }, + { + "name": "sender", + "unit": "sender of this message", + "type": "integer" + }, + { + "name": "receiver", + "unit": "receiver of this message", + "type": "integer" + }, + { + "name": "measurement_type", + "unit": "measurement_type of this message", + "type": "integer" + }, + { + "name": "measurement_value", + "unit": "measurement_value of this message", + "type": "float" + } + ], + "vectorize": 1, + "enabled": true + } + } +} \ No newline at end of file diff --git a/include/behavior/ref_intcomm/refic_df_behavior.h b/include/behavior/ref_intcomm/refic_df_behavior.h index 0e7356ef41a82a915fcc04b15be515c5910b79f8..c8176b6145b41850f8906875739de24c8ffd4c05 100644 --- a/include/behavior/ref_intcomm/refic_df_behavior.h +++ b/include/behavior/ref_intcomm/refic_df_behavior.h @@ -28,7 +28,7 @@ class Refic_df_behavior : public Agent_behavior { public: Refic_df_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, int rank); - ~Refic_df_behavior() override; + ~Refic_df_behavior() override = default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/ref_intcomm/refic_prosumer_behavior.h b/include/behavior/ref_intcomm/refic_prosumer_behavior.h index 4b01c9840e05a7b4e27f8e64d537fa49898aca86..633a62aabe96aec895f0306ddec744dc4a8d8463 100644 --- a/include/behavior/ref_intcomm/refic_prosumer_behavior.h +++ b/include/behavior/ref_intcomm/refic_prosumer_behavior.h @@ -28,7 +28,7 @@ class Refic_prosumer_behavior : public Agent_behavior { public: Refic_prosumer_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data); - ~Refic_prosumer_behavior() override; + ~Refic_prosumer_behavior() override = default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/ref_intcomm/refic_slack_behavior.h b/include/behavior/ref_intcomm/refic_slack_behavior.h index aba5169ad32b03b21afeb8eeb161f3d3f4be19c8..aa49c7a4a3c3c1ccc9c2e54985b539e4f33df2a4 100644 --- a/include/behavior/ref_intcomm/refic_slack_behavior.h +++ b/include/behavior/ref_intcomm/refic_slack_behavior.h @@ -27,7 +27,7 @@ class Refic_slack_behavior : public Agent_behavior { public: Refic_slack_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props); - ~Refic_slack_behavior() override; + ~Refic_slack_behavior() override = default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/ref_intcomm/refic_substation_behavior.h b/include/behavior/ref_intcomm/refic_substation_behavior.h index 797fbd8cf8872ac28b5e51f8e2d847ea11b26064..111bd1a62cb0578c0df790d634424830911b9e88 100644 --- a/include/behavior/ref_intcomm/refic_substation_behavior.h +++ b/include/behavior/ref_intcomm/refic_substation_behavior.h @@ -29,7 +29,7 @@ class Refic_substation_behavior : public Agent_behavior { public: Refic_substation_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Substation_data * _substation_data); - ~Refic_substation_behavior() override; + ~Refic_substation_behavior() override = default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/reference/ref_df_behavior.h b/include/behavior/reference/ref_df_behavior.h index c3eaee3f99e46862eb5a191f85bc508b6fb574af..84ac0d750a577d44c677f47dd2aa0c934605e2ba 100644 --- a/include/behavior/reference/ref_df_behavior.h +++ b/include/behavior/reference/ref_df_behavior.h @@ -28,7 +28,7 @@ class Ref_df_behavior : public Agent_behavior { public: Ref_df_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, int rank); - ~Ref_df_behavior() override; + ~Ref_df_behavior() override =default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/reference/ref_prosumer_behavior.h b/include/behavior/reference/ref_prosumer_behavior.h index e75685b43f3ddc11f35c6498af9400ca06ba4bec..152e1a34380bd42480543fe418e1d7ed18ccfd08 100644 --- a/include/behavior/reference/ref_prosumer_behavior.h +++ b/include/behavior/reference/ref_prosumer_behavior.h @@ -29,7 +29,7 @@ class Ref_prosumer_behavior : public Agent_behavior { public: Ref_prosumer_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data); - ~Ref_prosumer_behavior() override; + ~Ref_prosumer_behavior() override =default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/reference/ref_slack_behavior.h b/include/behavior/reference/ref_slack_behavior.h index c16f6f2554bd08f692d77cc1027bdf4bfe8fe95c..60d95237a0af4e5cebade100eda6ba2aee71a691 100644 --- a/include/behavior/reference/ref_slack_behavior.h +++ b/include/behavior/reference/ref_slack_behavior.h @@ -27,7 +27,7 @@ class Ref_slack_behavior : public Agent_behavior { public: Ref_slack_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props); - ~Ref_slack_behavior() override; + ~Ref_slack_behavior() override =default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/reference/ref_substation_behavior.h b/include/behavior/reference/ref_substation_behavior.h index d329186f4dcea98392631ea8af5832fa6c15e73a..d2e25bee60f2fa268ce8b81303cc82b01185d343 100644 --- a/include/behavior/reference/ref_substation_behavior.h +++ b/include/behavior/reference/ref_substation_behavior.h @@ -29,7 +29,7 @@ class Ref_substation_behavior : public Agent_behavior { public: Ref_substation_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Substation_data * _substation_data); - ~Ref_substation_behavior() override; + ~Ref_substation_behavior() override =default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/swarmgrid/swarm_behavior.h b/include/behavior/swarmgrid/swarm_behavior.h index 274df3fd83c42cd6f0634f67708c15b3abc2c46c..0935481a44a707fe08ef36ac75e281928904cacc 100644 --- a/include/behavior/swarmgrid/swarm_behavior.h +++ b/include/behavior/swarmgrid/swarm_behavior.h @@ -30,7 +30,7 @@ class Swarm_behavior : public Agent_behavior { public: Swarm_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props); - virtual ~Swarm_behavior() override = default; + ~Swarm_behavior() override = default; protected: /* message processing */ diff --git a/include/behavior/swarmgrid/swarm_df_behavior.h b/include/behavior/swarmgrid/swarm_df_behavior.h index 5b915c290b04081b30beb973d81e8fd18170b2f6..48fb200d7bd808155bcc48e041ad81e81849a7b9 100644 --- a/include/behavior/swarmgrid/swarm_df_behavior.h +++ b/include/behavior/swarmgrid/swarm_df_behavior.h @@ -30,7 +30,7 @@ class Swarm_df_behavior : public Swarm_behavior { public: Swarm_df_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, DF_data * _df_data, int _rank); - ~Swarm_df_behavior() override; + ~Swarm_df_behavior() override =default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.h b/include/behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.h deleted file mode 100644 index df388f1ccf5edf3821e8d0dc61877a0f30315d9d..0000000000000000000000000000000000000000 --- a/include/behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * This file is part of DistAIX - * - * 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 . - *********************************************************************************/ - - -#ifndef SWARM_DPSIM_COSIM_SLACK_BEHAVIOR -#define SWARM_DPSIM_COSIM_SLACK_BEHAVIOR - -#include "behavior/swarmgrid/swarm_slack_behavior.h" -#include "behavior/dpsim_cosim/dpsim_cosim_message.h" - - -//forwad declarations -struct villas_node_config; - -/*! \brief Class for dpsim cosim with swarm behavior - * */ - -class Swarm_dpsim_cosim_slack_behavior : public Swarm_slack_behavior{ -public: - Swarm_dpsim_cosim_slack_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, struct data_props _d_props, - Slack_data * _slack_data, villas_node_config * _villas_config, bool _realtime, bool _sync); - - ~Swarm_dpsim_cosim_slack_behavior(); - - - int initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file); - void report_to_superior_grid(Dpsim_cosim_msg message, std::list *incoming_villas_messages); - - -private: - void create_endpoints(villas_node_config * _vnconfig, std::string agent_id); - - void receive_message(std::list *incoming_villas_messages); - void synchronize_with_remote(); - - int busy_receive_msg(std::list *incoming_villas_messages); - void send_villas_msg(Dpsim_cosim_msg message); - - struct villas_node_config * vnconfig; - - int sender; - double step_size; - - bool first_step = true; - bool realtime; - bool sync; - - int timeout = 5000; // timeout for busy waiting in milliseconds - - unsigned int numOfSentMessages = 0; - unsigned int numOfReceivedMessages = 0; - -}; - -#endif // DPSIM_COSIM_SLACK_BEHAVIOR \ No newline at end of file diff --git a/include/behavior/swarmgrid/swarm_negotiator_behavior.h b/include/behavior/swarmgrid/swarm_negotiator_behavior.h index 4d4c20656d1e39be6be83528f9603cedb07217b9..98a736c387ff2b53c88302f253d24ef395681312 100644 --- a/include/behavior/swarmgrid/swarm_negotiator_behavior.h +++ b/include/behavior/swarmgrid/swarm_negotiator_behavior.h @@ -36,7 +36,7 @@ class Swarm_negotiator_behavior : public Swarm_behavior { public: Swarm_negotiator_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props); - virtual ~Swarm_negotiator_behavior() override = default; + ~Swarm_negotiator_behavior() override = default; protected: /* message processing */ diff --git a/include/behavior/swarmgrid/swarm_prosumer_behavior.h b/include/behavior/swarmgrid/swarm_prosumer_behavior.h index dcb899caedc1867f1e7be7c2bd0fbddcb6219786..41662b3e83bcb7cb8dc5b91c7a699cddefa5a005 100644 --- a/include/behavior/swarmgrid/swarm_prosumer_behavior.h +++ b/include/behavior/swarmgrid/swarm_prosumer_behavior.h @@ -32,7 +32,7 @@ class Swarm_prosumer_behavior : public Swarm_negotiator_behavior { public: Swarm_prosumer_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data); - virtual ~Swarm_prosumer_behavior() override; + ~Swarm_prosumer_behavior() override =default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/swarmgrid/swarm_slack_behavior.h b/include/behavior/swarmgrid/swarm_slack_behavior.h index 044ec419e0857bd75b124e21662fca34d645b904..3293f3f6424db1b1167ca2cd4a83eb429398617b 100644 --- a/include/behavior/swarmgrid/swarm_slack_behavior.h +++ b/include/behavior/swarmgrid/swarm_slack_behavior.h @@ -30,7 +30,7 @@ class Swarm_slack_behavior : public Swarm_negotiator_behavior { public: Swarm_slack_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Slack_data * _slack_data); - virtual ~Swarm_slack_behavior() override; + ~Swarm_slack_behavior() override = default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/behavior/swarmgrid/swarm_substation_behavior.h b/include/behavior/swarmgrid/swarm_substation_behavior.h index 95b28eab7d5726c78081176358b12bac20d957f9..4c1e563892c484cd67b87644b76c3304662d3755 100644 --- a/include/behavior/swarmgrid/swarm_substation_behavior.h +++ b/include/behavior/swarmgrid/swarm_substation_behavior.h @@ -34,7 +34,7 @@ class Swarm_substation_behavior : public Swarm_negotiator_behavior { public: Swarm_substation_behavior(int _id, int _type, std::string _subtype, double& step_size, struct data_props _d_props, Substation_data * _substation_data); - virtual ~Swarm_substation_behavior() override; + ~Swarm_substation_behavior() override = default; int initialize_agent_behavior(std::vector>> * components_at_nodes, std::vector>> * connected_nodes, diff --git a/include/model/model.h b/include/model/model.h index e3b96b326a0d5d58a8b893f83e07360b22f1f1dc..ecd019385cb6a37c60a22fda6f1ddb1b22bb8161 100644 --- a/include/model/model.h +++ b/include/model/model.h @@ -19,7 +19,11 @@ #define MODEL #include +#if (BOOST_VERSION >= 107200) +#include +#else #include +#endif #include #include @@ -39,10 +43,6 @@ #include "model_io.h" #include "model_creator.h" -//Forward declarations -class Villas_interface; -struct villas_node_config; - class Model_creator; /*! \brief class describing the model owned by every MPI process @@ -156,7 +156,11 @@ protected: /*progress bar*/ +#if (BOOST_VERSION >= 107200) + boost::timer::progress_display *progress_p; //!< Fancy progress bar of boost library +#else boost::progress_display *progress_p; //!< Fancy progress bar of boost library +#endif /*Variables that contain agent selections*/ std::vector local_agents; //!< Vector of agents that belong to this process @@ -208,16 +212,10 @@ protected: /* MPI communicator for FBS*/ MPI_Comm filled_ranks; //. - *********************************************************************************/ - -#ifndef VILLAS_INTERFACE_H -#define VILLAS_INTERFACE_H - -#include -#include -#include "villas_interface/villas_message.h" - -//forward declarations -struct vnode; -struct vnode_type; -struct pool; - -class IO_object; - -#define DEFAULT_NUMBER_OF_SAMPLES 1 -#define DEFAULT_LENGTH_OF_SAMPLE 64 - -//copied from villas utils.h -/** Get nearest up-rounded power of 2 */ -#define MY_LOG2_CEIL(x) (1 << (my_log2i((x) - 1) + 1)) - -/** Get log2 of long long integers */ -static inline int my_log2i(long long x) { - if (x == 0) - return 1; - - return sizeof(x) * 8 - __builtin_clzll(x) - 1; -} - - -/*! \brief Struct that holds general info about the villas node type MQTT */ -struct mqtt_data{ - std::string broker; - int port; - int retain; - int keepalive; - std::string publish; - std::string subscribe; - int qos; - - int ssl_enabled; - int ssl_insecure; - int ssl_cert_reqs; - std::string ssl_tls_version; - std::string ssl_cafile; - std::string ssl_capath; - std::string ssl_certfile; - std::string ssl_ciphers; - std::string ssl_keyfile; - -}; - -/*! \brief Struct that holds general info about the villas node type nanomsg */ -struct nanomsg_data{ - std::list in_endpoints; - std::list out_endpoints; -}; - -/*! \brief Struct that holds general info about the villas node */ -struct villas_node_config{ - std::string type_name; - std::string format_name; - std::string loglevel; - bool with_node; - double stop_at; // used to synchronize end of simulation in cosimulation - union node_type_config{ - mqtt_data *mqtt_conf; - nanomsg_data *nanomsg_conf; - } type_config; -}; - - -class Villas_interface{ - -public: - Villas_interface(villas_node_config *_config, IO_object *IO_obj, std::string _name, std::vector &_meta); - ~Villas_interface(); - - //methods to send/receive data via villas node - void send_message(Villas_message &msg); - void receive_messages(std::list &messages); - //methods to start/stop the villas node - int start(); - int stop(); - //methods to init/destroy the villas node - int destroy(); - - //methods to control villas node type (used by model ONLY) - int start_node_type(); - int stop_node_type(); - - -private: - /*VillasNode struct*/ - struct vnode *n; - struct vnode_type *type; - - //Memory pool - struct pool *p; - - // meta infos - std::vector meta; - - //counting number of sent messages for sequence numbers - unsigned int number_of_sent_messages; - bool with_node; - - //for logging into agent log file - IO_object *IO; - - void allocate_and_receive(int number_of_messages, std::list &messages); - -}; - -#endif //VILLAS_INTERFACE_H diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 3b04e94168fac2c2913c70ba6bdeac8558893204..ebd7a39b0bb2b316c76ea8cf9826cd4949e13452 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -26,14 +26,12 @@ add_subdirectory(repast_hpc) #fbs-components library (as submodule) add_subdirectory(fbs-components) + if(WITH_VILLAS) - #villas library (as submodule) - set(WITH_HOOKS OFF CACHE BOOL "disable hooks of libvillas") - set(WITH_WEB OFF CACHE BOOL "disable web of libvillas") - set(WITH_API OFF CACHE BOOL "disable api of libvillas") - set(NO_EVENTFD 1 CACHE BOOL "do not use event file descriptors in libvillas") - add_subdirectory(villasnode) + #VILLAS interface library (required for behaviors that use VILLASnode) + add_subdirectory(villas-interface) endif() + if(WITH_DB) #DBconnector library add_subdirectory(dbconnector) diff --git a/libs/fbs-components b/libs/fbs-components index 45383506d83cbbedd348eef0f1b807414d2667f2..5a1c963d03c50d701244af8fbd576e9f374d3266 160000 --- a/libs/fbs-components +++ b/libs/fbs-components @@ -1 +1 @@ -Subproject commit 45383506d83cbbedd348eef0f1b807414d2667f2 +Subproject commit 5a1c963d03c50d701244af8fbd576e9f374d3266 diff --git a/libs/villas-interface/CMakeLists.txt b/libs/villas-interface/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1043a4b3fa1754e04939a914fffc66aec5704e4d --- /dev/null +++ b/libs/villas-interface/CMakeLists.txt @@ -0,0 +1,61 @@ +############################################################################# +# +# This file is part of DistAIX FBScomponents +# +# 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 . +############################################################################# + + +cmake_minimum_required(VERSION 3.0) +project(villas-interface) + +include(FindPkgConfig) + +# create source list +file(GLOB_RECURSE SRC_LIST ./src/*.cpp) + +#set compiler flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -std=c++11 -Wall") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -std=c++11 -Wall") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +# add villas library (as submodule) +set(WITH_HOOKS OFF CACHE BOOL "disable hooks of libvillas") +set(WITH_WEB OFF CACHE BOOL "disable web of libvillas") +set(WITH_API OFF CACHE BOOL "disable api of libvillas") +set(WITH_GO OFF CACHE BOOL "disable go functions of villasnode") +set(WITH_TESTS OFF CACHE BOOL "disable tests of villasnode") +set(WITH_TOOLS OFF CACHE BOOL "disable tools of villasnode") +set(WITH_SRC OFF CACHE BOOL "disable executables of villasnode") +set(DOWNLOAD_GO OFF CACHE BOOL "disable download of go toolchain in villasnode") +set(NO_EVENTFD 1 CACHE BOOL "do not use event file descriptors in libvillas") + +# disable NSGI node type because of bug in this villasnode type for OpenSSL versions < 1.0.3 +pkg_search_module(OPENSSL openssl) +if( ${OPENSSL_VERSION} VERSION_LESS "1.0.3" ) + set(WITH_NODE_NGSI OFF CACHE BOOL "disable NGSI node type of villasnode") +endif() + +add_subdirectory(villasnode) + +#create shared library +add_library(villas-interface SHARED ${SRC_LIST}) + +target_include_directories(villas-interface SYSTEM PUBLIC include villasnode/include) + +#add additional libraries to link to (currently not required) +target_link_libraries(villas-interface villas) + +#additional definitions (currently NONE) +#add_definitions() \ No newline at end of file diff --git a/libs/villas-interface/include/villas_interface.h b/libs/villas-interface/include/villas_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..165c876595fe98db6fa9ee163425559cc6403824 --- /dev/null +++ b/libs/villas-interface/include/villas_interface.h @@ -0,0 +1,63 @@ +/** + * This file is part of DistAIX + * + * 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 . + *********************************************************************************/ + +#ifndef VILLAS_INTERFACE_H +#define VILLAS_INTERFACE_H + +#include +#include +#include +#include "villas_message.h" +#include "villas/node.hpp" +#include "villas/pool.hpp" + + +class Villas_interface{ + +public: + explicit Villas_interface(std::string &custom_params_json_string); + ~Villas_interface(); + + //methods to send/receive data via villas node + int send(Villas_message &msg); + int receive(std::list &messages, int to_be_received, bool single_read); + + //static methods to control villas node type process-wide + static int start_node_type(std::string &config_file_path, int rank); /*process-wide starting of global villasnode*/ + static int stop_node_type(); /*process-wide stopping of global villasnode*/ + static std::string type; /*process-wide type of villasnodes*/ + static uuid_t supernode_uuid; /*process-wide uuid used in villasnode instantiation*/ + +private: + + /* static members for process-wide use*/ + static json_t *base_conf; /*base VILLASnode config in JSON format provided by the user*/ + static villas::node::Node *global_node; /*global process-wide node for process-wide inits*/ + + villas::node::Node *n; /*VillasNode instance used by agent*/ + villas::node::Pool p; //Memory pool instance used by agent + unsigned int number_of_sent_messages; //counting number of sent messages for sequence numbers + + int allocate_and_receive(int number_of_messages, std::list &messages, bool single_read); + + //methods to init/start/stop the villas node + int init(std::string &custom_params_json_string); + int start(); + int stop(); +}; + +#endif //VILLAS_INTERFACE_H diff --git a/include/villas_interface/villas_message.h b/libs/villas-interface/include/villas_message.h similarity index 70% rename from include/villas_interface/villas_message.h rename to libs/villas-interface/include/villas_message.h index 6cf7c1648c982ab0be85fc9c95ae870c72a140f2..761f52ee222a1ce7dba6960c8097f673962d9a3c 100644 --- a/include/villas_interface/villas_message.h +++ b/libs/villas-interface/include/villas_message.h @@ -21,17 +21,13 @@ #include #include #include +#include "villas/sample.hpp" +#include "villas/node.hpp" -#define VILLAS_DATA_TYPE_DOUBLE 1 -#define VILLAS_DATA_TYPE_INT64 2 -#define VILLAS_DATA_TYPE_BOOLEAN 3 -#define VILLAS_DATA_TYPE_COMPLEX 4 - -struct Meta_infos{ - std::string name; - std::string unit; - int type; -}; +#define VILLASMSG_BOOLEAN 0 +#define VILLASMSG_INTEGER 1 +#define VILLASMSG_FLOAT 2 +#define VILLASMSG_COMPLEX 3 union Data_element{ double f; @@ -48,14 +44,18 @@ class Villas_message{ public: Villas_message(); + Villas_message(villas::node::Sample *s); + Villas_message(const Villas_message &msg); virtual ~Villas_message() = default; - void add_element(Data_element _d, int _type); + int toSample(villas::node::Sample * s, villas::node::Node * n, unsigned int number_of_sent_messages); + std::string toString(); std::vector data; - double time_sec; //!< simulation time when message is sent (has to be set manually before calling send_message()) + std::vector data_types; + double time_sec; //!< simulation time when message is sent (has to be set manually before calling send()) unsigned int length; }; -#endif //DISTAIX_VILLAS_MESSAGE_H +#endif //DISTAIX_VILLAS_MESSAGE_H \ No newline at end of file diff --git a/libs/villas-interface/src/villas_interface.cpp b/libs/villas-interface/src/villas_interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89cff118a5afc7ba7164dc5f9c11fdbb6769e13c --- /dev/null +++ b/libs/villas-interface/src/villas_interface.cpp @@ -0,0 +1,455 @@ +/** + * This file is part of DistAIX + * + * 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 . + *********************************************************************************/ + + +#include "villas_interface.h" +#include +#include +#include "jansson.h" + + +json_t * Villas_interface::base_conf; +villas::node::Node * Villas_interface::global_node; +uuid_t Villas_interface::supernode_uuid; + +/*! \brief Constructor of Villas_interface class, creates and starts villas node instance + * \param custom_params_json_string json string containing custom parameters for villas node such as name + */ +Villas_interface::Villas_interface(std::string &custom_params_json_string) { + number_of_sent_messages = 0; + n = nullptr; + p.state = State::DESTROYED; + + int ret; + ret = this->init(custom_params_json_string); + if (ret){ + throw std::runtime_error("error on VILLASnode init, return code " + std::to_string(ret)); + } + ret = this->start(); + if (ret){ + throw std::runtime_error("error on VILLASnode start, return code " + std::to_string(ret)); + } + +} + +/*! \brief Destructor of Villas_interface class + * */ +Villas_interface::~Villas_interface() { + //disconnect + int ret = this->stop(); + if (ret){ + std::cerr << "Warning: error stopping villas node, return value: " << ret << ". I will not attempt to delete the node." <check(); + if (ret) { + std::cerr << "Villas_interface::init: node check returned with error " << ret << std::endl; + return ret; + } + + // prepare VILLASnode + ret = n->prepare(); + if (ret) { + std::cerr << "Villas_interface::init: node prepare returned with error " << ret << std::endl; + return ret; + } + + // init memory pool + //Allocate 1MB of pool memory for sent and received messages + //200 kiByte = 204800 + //1 MiB = 1048576 + try { + size_t blocksize = sizeof(struct villas::node::Sample) + (n->getInputSignals()->size()) * sizeof(double); + ret = villas::node::pool_init(&p, 1024, blocksize, &(villas::node::memory::heap)); + if (ret) { + std::cerr << "Villas_interface::init: pool_init returned with error " << ret << std::endl; + return ret; + } + + } catch (villas::MemoryAllocationError &err) { + std::cerr << "Villas_interface::init: caught VILLAS MemoryAllocationError on pool_init: " << err.what() << std::endl; + return -1; + } catch (villas::RuntimeError &err ) { + std::cerr << "Villas_interface::init: caught VILLAS RuntimeError on pool_init: " << err.what() << std::endl; + return -1; + } + + return 0; +} + +/*! \brief Start VILLASnode + * */ +int Villas_interface::start() { + try { + int ret = n->start(); + std::cerr << "Villas_interface::start: VILLASnode start returned with error " << ret << std::endl; + return ret; + }catch (villas::RuntimeError &err){ + std::cerr << "Villas_interface::start start villas node caught Villas runtime error: " << err.what() << std::endl; + return -1; + } +} + + +/*! \brief Stop VILLASnode + * */ +int Villas_interface::stop() { + + int ret = n->stop(); + if (ret) { + std::cerr << "Villas_interface::stop: VILLASnode stop returned with error: " << ret << std::endl; + } + return ret; +} + + +/*! \brief Send a message via a Villas_interface + * \param msg message to be sent + * \return number of sent messages on success or integer <0 on error + * */ +int Villas_interface::send(Villas_message &msg) { + struct villas::node::Sample * s = villas::node::sample_alloc(&p); + int ret = msg.toSample(s, n, number_of_sent_messages); + if(ret){ + std::cerr << "Villas_interface::send: msg.toSample returned with error: " << ret << std::endl; + return ret; + } + + villas::node::Sample *smps[1] = {s}; + // send sample + int sent = n->write(smps, n->out.vectorize); + + villas::node::sample_decref(s); + villas::node::sample_free(s); + + if (sent < 0) { // check for error + std::cerr << "Villas_interface::send: VILLASnode write returned with error: " << ret << std::endl; + return sent; + } + number_of_sent_messages++; // increase number of sent messages only of no error + return sent; +} + + +/*! \brief Reserve memory for from pool for message reception and receive messages + * \param number_of_messages exact number of messages to be received + * \param messages reference to message vector that contains received messages after this method is finished + * \param single_read true means that samples are read one by one until number_of_messages samples are read, false means all samples are read at once + * \return Number of received messages, integer <0 upon error + * */ +int Villas_interface::allocate_and_receive(int number_of_messages, std::list &messages, bool single_read) { + + if(number_of_messages > 0) { + struct villas::node::Sample *samples[number_of_messages]; + int allocated = villas::node::sample_alloc_many(&p, samples, number_of_messages); + + if (single_read){ // Read samples one by one (for node types that have no queue or message buffering) + struct villas::node::Sample * s = villas::node::sample_alloc(&p); + + int received = 0; + unsigned int index = 0; + + for (int i = 0; i < number_of_messages; ++i){ + + villas::node::Sample *smps[1] = {s}; + int recv = n->read(smps, 1); + if (recv > 0){ + sample_copy(samples[index], s); + received++; + index++; + } + } + if (received > 0){ + number_of_messages = received; + } + else { // Skip error output as nanomsg polling is based on reading empty socket + number_of_messages = 0; + } + + // Free allocated memory for temporary sample + villas::node::sample_decref(s); + villas::node::sample_free(s); + } + else { // read samples at once (for node types that have a queue/ message buffering) + //receive sample + int recv = n->read(samples, number_of_messages); + + if (recv < 0) { + return recv; + } + } + + // process received samples to message + for (int x = 0; x < number_of_messages; x++) { + + Villas_message new_msg(samples[x]); + messages.push_back(new_msg); + } + + villas::node::sample_decref_many(samples, allocated); + villas::node::sample_free_many(samples, allocated); + return number_of_messages; + } + return 0; +} + +/*! \brief Receive messages via VILLASnode + * \param messages reference to message vector that contains received messages after this method is finished + * \param to_be_received exact number of messages to be received + * \param single_read true means that samples are read one by one until number_of_messages samples are read, false means all samples are read at once + * \return number of received messages, integer <0 on error + * */ +int Villas_interface::receive(std::list &messages, int to_be_received, bool single_read) { + + //receive all messages which are in incoming queue of villas node + messages.clear(); + int ret = allocate_and_receive(to_be_received, messages, single_read); + if (ret < 0){ + std::cerr << "Villas_interface::receive: VILLASnode read returned with error: " << ret << std::endl; + } + return ret; +} + +/*! \brief Method to start a node type; should only be called once per process + * \param config_file_path path to the JSON config file for VILLASnode + * \param rank rank that is calling this method + * \return 0 on success, value different from 0 on error + * + * */ +int Villas_interface::start_node_type(std::string &config_file_path, int rank) { + + int ret; + json_error_t err; + + json_t *config = json_object(); + config = json_load_file(config_file_path.c_str(), 0, &err); + if (!config) { + std::cerr << "Villas_interface::start_node_type: Rank " << rank << ": error loading villas json config: in line " << err.line << " " << err.text + << std::endl; + return -1; // error reading villas config json + } + + json_t *json_logging = nullptr; + json_t *json_node = nullptr; + int hugepages = 0; + + ret = json_unpack_ex(config, &err, 0, "{ s?: i, s?: o, s?: o}", + "hugepages", &hugepages, + "logging", &json_logging, + "node", &json_node + ); + if (ret) { + std::cerr << "Villas_interface::start_node_type: Rank " << rank << ": error unpacking villas json config: in line " << err.line << " " << err.text + << std::endl; + return ret; + } + + /* Save base config of VILLASnodes used in this process */ + Villas_interface::base_conf = json_deep_copy(json_node); + if (Villas_interface::base_conf == nullptr) { + std::cerr << "Villas_interface::start_node_type: Rank " << rank << ": error on deep copy of json config" << std::endl; + return -1; // error on deep copy + } + + /*adapt log file name*/ + const char *key; + json_t *value; + void *iter = json_object_iter(json_logging); + ret = 0; + while (iter) { + key = json_object_iter_key(iter); + value = json_object_iter_value(iter); + std::string filename = json_string_value(value) + std::to_string(rank) + ".log"; + if (!strcmp(key, "file")) { + ret = json_object_set(json_logging, "file", json_string(filename.c_str())); + break; + } + iter = json_object_iter_next(json_logging, iter); + } + + if (ret) { + std::cerr << "Villas_interface::start_node_type: Rank " << rank << ": error on updating VILLAS logging file name: " << ret << std::endl; + return -1; + } + /*set logging param*/ + villas::logging.parse(json_logging); + + //init memory subsystem in each process + ret = villas::node::memory::init(hugepages); + if (ret) { + std::cerr << "Villas_interface::start_node_type: Rank " << rank << ": error on memory init for " << hugepages << " hugepages: "<< ret << std::endl; + return ret; + } + + /*extract node type from json */ + iter = json_object_iter(json_node); + while (iter) { + key = json_object_iter_key(iter); + value = json_object_iter_value(iter); + if (!strcmp(key, "type")) { + // save type of VILLASnode + Villas_interface::type = json_string_value(value); + break; + } + } + + /*create uuid and save it*/ + uuid_generate(Villas_interface::supernode_uuid); + + // instantiate the node type + try { + Villas_interface::global_node = villas::node::NodeFactory::make(Villas_interface::type); + } catch (villas::RuntimeError &err) { + std::cerr << "Global VILLASnode init caught villas runtime error: " << err.what() << std::endl; + return -1; + } + + //start node type + auto *nf = Villas_interface::global_node->getFactory(); + + if (nf == nullptr){ + std::cerr << "Global VILLASnode init: could not fetch node factory of global node in rank " << rank << std::endl; + return -1; + } + + if (nf->getState() != State::STARTED) { + // nullptr in the following as argument will not work for all node types! + // parameter expects pointer to VILLAS supernode + ret = nf->start(nullptr); + if (ret) { + std::cerr << "Global VILLASnode init: global VILLASnode start returned with error " << ret << " in rank " << rank << std::endl; + } + return ret; + } + return 0; +} + + +/*! \brief Method to stop a node type; should only be called once per process + * */ +int Villas_interface::stop_node_type() { + //stop node type + auto *nf = Villas_interface::global_node->getFactory(); + if (nf == nullptr){ + std::cerr << "Warning: Global VILLASnode cleanup: could not fetch node factory of global node in rank " << std::endl; + } else { + if (nf->getState() == State::STARTED) { + int ret = nf->stop(); + if (ret){ + std::cerr << "Warning: Global VILLASnode cleanup: error on stopping global VILLASnode instance, returned with " << ret << std::endl; + } + } + } + + delete Villas_interface::global_node; + delete Villas_interface::base_conf; + + return 0; +} + diff --git a/libs/villas-interface/src/villas_message.cpp b/libs/villas-interface/src/villas_message.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd3d22494d4630c1a5a054b60be27983352b5bab --- /dev/null +++ b/libs/villas-interface/src/villas_message.cpp @@ -0,0 +1,163 @@ +/** + * This file is part of DistAIX + * + * 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 . + *********************************************************************************/ + +#include + +Villas_message::Villas_message() { + length =0; + data.clear(); + data_types.clear(); + time_sec = 0.0; +} + +Villas_message::Villas_message(const Villas_message &msg) { + data = msg.data; + data_types = msg.data_types; + length = msg.length; + time_sec = msg.time_sec; +} + +Villas_message::Villas_message(villas::node::Sample *s) { + + data.clear(); + data_types.clear(); + length = 0; + for (unsigned int i = 0; i < s->length; i++) { + Data_element d; + + switch (s->signals->getByIndex(i)->type) { + + case villas::node::SignalType::INVALID: + break; + case villas::node::SignalType::FLOAT: + d.f = s->data[i].f; + data.push_back(d); + data_types.push_back(VILLASMSG_FLOAT); + length++; + break; + case villas::node::SignalType::INTEGER: + d.i = s->data[i].i; + data.push_back(d); + data_types.push_back(VILLASMSG_INTEGER); + length++; + break; + case villas::node::SignalType::BOOLEAN: + d.b = s->data[i].b; + data.push_back(d); + data_types.push_back(VILLASMSG_BOOLEAN); + length++; + break; + case villas::node::SignalType::COMPLEX: + d.z = s->data[i].z; + data.push_back(d); + data_types.push_back(VILLASMSG_COMPLEX); + length++; + break; + } + } + + //set time + time_sec = (double) s->ts.origin.tv_sec + + ((double) s->ts.origin.tv_nsec / 1000000000.0); +} + +/*! \brief transform message to VILLASnode sample data type + * */ +int Villas_message::toSample(villas::node::Sample *s, villas::node::Node * n, unsigned int number_of_sent_messages) { + + //fill sample + s->length = length; + s->sequence = number_of_sent_messages; + //s->signals = n->getOutputSignals(); + s->signals = n->getInputSignals(false); + + if(s->signals == nullptr || s->signals->size() != length){ + std::cerr << "ERROR no signals returned from VILLASnode" << std::endl; + return -1; // error, no signals or message length and signal list length do not match! + } + + for(unsigned int k = 0; k< length; k++){ + + switch (s->signals->getByIndex(k)->type){ + + case villas::node::SignalType::INVALID: + break; + case villas::node::SignalType::FLOAT: + s->data[k].f = data[k].f; + break; + case villas::node::SignalType::INTEGER: + s->data[k].i = data[k].i; + break; + case villas::node::SignalType::BOOLEAN: + s->data[k].b = data[k].b; + break; + case villas::node::SignalType::COMPLEX: + s->data[k].z = data[k].z; + break; + } + } + + s->ts.origin.tv_sec = (long int) time_sec; + double nano_sec = (time_sec- (double) s->ts.origin.tv_sec) * 1000000000; + s->ts.origin.tv_nsec = (long int) (nano_sec); + + //set flags of sample + s->flags = 0; + s->flags |= (unsigned int) villas::node::SampleFlags::HAS_DATA; + + return 0; +} + +/*! +* \brief Writes the content of a message to a string for debugging +* \return Message content as string +* */ +std::string Villas_message::toString() { + std::stringstream temp; + std::string output; + + temp << "( "; + int counter = 0; + if (data.size() != data_types.size()){ + temp << "mismatch between data and data types of message, print not possible )" << std::endl; + } else { + for (const auto &d: data) { + + switch (data_types[counter]) { + case VILLASMSG_FLOAT: + temp << d.f; + break; + case VILLASMSG_INTEGER: + temp << d.i; + break; + case VILLASMSG_BOOLEAN: + temp << d.b; + break; + case VILLASMSG_COMPLEX: + temp << d.z; + break; + default: + temp << "unknown type"; + } + temp << " | "; + counter++; + } + temp << ") " << std::endl; + } + output = temp.str(); + return output; +} diff --git a/libs/villas-interface/villasnode b/libs/villas-interface/villasnode new file mode 160000 index 0000000000000000000000000000000000000000..69c70d17bcbd01f2496848f6ac748fc90ae3e696 --- /dev/null +++ b/libs/villas-interface/villasnode @@ -0,0 +1 @@ +Subproject commit 69c70d17bcbd01f2496848f6ac748fc90ae3e696 diff --git a/libs/villasnode b/libs/villasnode deleted file mode 160000 index e0242dc544a3138e56cb550e5c9b9d12ae979593..0000000000000000000000000000000000000000 --- a/libs/villasnode +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e0242dc544a3138e56cb550e5c9b9d12ae979593 diff --git a/props/model.props b/props/model.props index 7a9d7beeef0f89ed2b5be2e0b37000330d0b13de..4f363a984c040627c1dd8928b8437d9fa21e65a6 100644 --- a/props/model.props +++ b/props/model.props @@ -160,36 +160,5 @@ cassandra.iothreads = 10 ######################################## # parameters for villas usage -# supported node types: mqtt, nanomsg -villas.nodetype = mqtt -villas.format = json -villas.loglevel = debug - -# MQTT specific parameters -villas.mqtt.broker = localhost -villas.mqtt.port = 1883 -villas.mqtt.qos = 0 -villas.mqtt.retain = 0 -villas.mqtt.keepalive = 5 -villas.mqtt.ssl_enabled = 0 -villas.mqtt.ssl_insecure = 1 -# SSL Cert. requirements: SSL_VERIFY_NONE(0) or SSL_VERIFY_PEER(1) -villas.mqtt.ssl_cert_reqs = 0 -villas.mqtt.ssl_cafile = cafile -villas.mqtt.ssl_capath = capath -villas.mqtt.ssl_certfile = certfile -villas.mqtt.ssl_keyfile = keyfile -villas.mqtt.ssl_ciphers = ciphers -villas.mqtt.ssl_tls_version = 1.3 - -# set a default topic to which all agents subscribe/ publish -# per default if nothing else is specified in the agent's behavior -villas.mqtt.subscribe = testtopic -villas.mqtt.publish = testtopic - -# Nanomsg specific parameters -# for cosimulation: -# in.endpoint --> remote -# out.endpoint --> local -villas.nanomsg.in_endpoints = ipc:///tmp/test1.ipc -villas.nanomsg.out_endpoints = ipc:///tmp/test1.ipc +villas.configfile = ../include/behavior/ensure/villas_mqtt_ensure.json +#villas.configfile = ../include/behavior/dpsim_cosim/villas_nanomsg_dpsim_cosim.json diff --git a/src/agents/agent.cpp b/src/agents/agent.cpp index 93a662244e017937f08bd0a88967384570e3636b..e65969928517115ed83a0396816e1875c2f90729 100644 --- a/src/agents/agent.cpp +++ b/src/agents/agent.cpp @@ -25,6 +25,8 @@ Agent::Agent(repast::AgentId &id, bool is_local): id_(id), is_local_instance(is_local){ msg_received=0; msg_sent=0; + behavior = nullptr; + IO = nullptr; } /*! \brief Constructor used for creation of copies of MR-agents @@ -37,6 +39,8 @@ Agent::Agent(repast::AgentId &id, bool is_local, std::list _msg_q outgoing_messages = std::move(_msg_queue); msg_received=0; msg_sent=0; + behavior = nullptr; + IO = nullptr; } /*! \brief Constructor used for creation of copies of Node, Transformer and Slack agents @@ -54,6 +58,8 @@ Agent::Agent(repast::AgentId &id, bool is_local, std::complex _current, { msg_received=0; msg_sent=0; + behavior = nullptr; + IO = nullptr; } /*! \brief Constructor used for creation of agents in model @@ -108,7 +114,14 @@ Agent::Agent(repast::AgentId &id, /*! \brief Destructor of Agent class * */ Agent::~Agent(){ - //interface.stop(); + if (is_local_instance) { + IO->log_info("Deleting agent"); + } + delete behavior; + if (is_local_instance) { + IO->finish_io(); + } + delete IO; } /*! \brief set data of agent @@ -351,17 +364,6 @@ int Agent::init_behavior(std::vector>> *comp return ret; } - -int Agent::villas_interface_disconnect() { - - if (behavior != nullptr) { - //destroy villas interface if this agent has a behavior - int ret = behavior->destroy_villas_interface(); - return ret; - } - return 0; -} - /*! \brief Set pointers of time measurements (called by model class for each agent) * \param _tm_csv pointer to time measurement for csv saving from model class * \param _tm_db pointer to time measurement for DB saving from model class diff --git a/src/agents/directoryfacilitator_agent.cpp b/src/agents/directoryfacilitator_agent.cpp index f4a66667c04421225dd69e576182088e5d968b09..f8adc21da8ea237833446aca69b6859af5f6db63 100644 --- a/src/agents/directoryfacilitator_agent.cpp +++ b/src/agents/directoryfacilitator_agent.cpp @@ -34,7 +34,6 @@ Directoryfacilitator_agent::Directoryfacilitator_agent(repast::AgentId &id, bool * \param _model_type [in] user selected type of el. models (0=static phasor models, 1=dynamic phasor models) * \param _subtype [in] subtype of the agent * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * */ Directoryfacilitator_agent::Directoryfacilitator_agent(repast::AgentId &id, bool is_local, @@ -42,8 +41,7 @@ Directoryfacilitator_agent::Directoryfacilitator_agent(repast::AgentId &id, int &_behavior_type, int &_model_type, std::string &_subtype, - struct data_props _d_props, - villas_node_config *_villas_config + struct data_props _d_props ) : Agent(id, is_local, step_size, _behavior_type, _model_type,_subtype, _d_props) { if (is_local_instance) { @@ -64,6 +62,7 @@ Directoryfacilitator_agent::Directoryfacilitator_agent(repast::AgentId &id, behavior = new Swarm_df_behavior(id_.id(), TYPE_DF_INT, _subtype, t_step, _d_props, &model_data, id_.currentRank()); break; } +#ifdef WITH_VILLAS case CTRL_MQTT_TEST:{ behavior = new Ref_df_behavior(id_.id(), TYPE_DF_INT, _subtype, t_step, _d_props, id_.currentRank()); break; @@ -76,6 +75,7 @@ Directoryfacilitator_agent::Directoryfacilitator_agent(repast::AgentId &id, behavior = new Swarm_df_behavior(id_.id(), TYPE_DF_INT, _subtype, t_step, _d_props, &model_data, id_.currentRank()); break; } +#endif case CTRL_INTCOMM:{ behavior = new Refic_df_behavior(id_.id(), TYPE_DF_INT, _subtype, t_step, _d_props, id_.currentRank()); break; @@ -88,13 +88,6 @@ Directoryfacilitator_agent::Directoryfacilitator_agent(repast::AgentId &id, } } - -/*! \brief Destructor of a Directory Faciliator agent*/ -Directoryfacilitator_agent::~Directoryfacilitator_agent() { - delete behavior; - IO->finish_io(); -} - /*! \brief Set the pointer to an Agent_scenario_creator object * \param _mc [in] Pointer to Model_creator object * */ diff --git a/src/agents/msgrouter_agent.cpp b/src/agents/msgrouter_agent.cpp index 7f0f014e14031d0f9b69a9369d8982dccfe79e8a..62b9a077900933914dda54492e1dab8a2a9b0964 100644 --- a/src/agents/msgrouter_agent.cpp +++ b/src/agents/msgrouter_agent.cpp @@ -31,7 +31,6 @@ Messagerouter_agent::Messagerouter_agent(repast::AgentId &id, bool is_local) : A * \param _model_type [in] user selected type of el. models (0=static phasor models, 1=dynamic phasor models) * \param _subtype [in] subtype of the agent * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * \param _use_commdata [in] true if latencies shall be taken from an input file, false if default latency shall be used * */ Messagerouter_agent::Messagerouter_agent(repast::AgentId &id, @@ -41,7 +40,6 @@ Messagerouter_agent::Messagerouter_agent(repast::AgentId &id, int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, bool &_use_commdata ) : Agent(id, is_local, step_size, _behavior_type, _model_type, _subtype, _d_props) { @@ -95,7 +93,7 @@ Messagerouter_agent::~Messagerouter_agent() { delete drop_probability_generator; delete drop_probability; delete mt_gen; - IO->finish_io(); + //IO->finish_io(); } diff --git a/src/agents/node_agent.cpp b/src/agents/node_agent.cpp index 8c18f88a8387019fb7f324a923ad999dbfa74cc8..88eca9f36354d1f75f551a0742906211c4ff5897 100644 --- a/src/agents/node_agent.cpp +++ b/src/agents/node_agent.cpp @@ -34,7 +34,6 @@ Node_agent::Node_agent(repast::AgentId &id, bool is_local) : Agent(id, is_local) * \param _model_type [in] user selected type of el. models (0=static phasor models, 1=dynamic phasor models) * \param _subtype [in] subtype of the agent * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * \param _ifht_id [in] ID of node in IFHT model * */ Node_agent::Node_agent(repast::AgentId &id, @@ -45,7 +44,6 @@ Node_agent::Node_agent(repast::AgentId &id, int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, int _ifht_id, bool _ict_connected ) : Agent(id, is_local, step_size, _behavior_type, _model_type, _subtype, _d_props) { @@ -72,12 +70,6 @@ Node_agent::Node_agent(repast::AgentId &id, model_data.ict_connected = _ict_connected; } -/*! \brief Destructor of Node_agent class - * */ -Node_agent::~Node_agent() { - IO->finish_io(); -} - /*! \brief advance a simulation step * */ void Node_agent::step() { diff --git a/src/agents/prosumer_agent.cpp b/src/agents/prosumer_agent.cpp index ac2c7d83226a6e5a31cae10b79bbf6665bbb1809..45d7881661b7f4a67ba661f8f3baef07d1396e67 100644 --- a/src/agents/prosumer_agent.cpp +++ b/src/agents/prosumer_agent.cpp @@ -48,7 +48,6 @@ Prosumer_agent::Prosumer_agent(repast::AgentId &id, bool is_local) : Agent(id, i * \param profiles [in] pointer to profile object * \param interpolation_type [in] interpolation type for the profile * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * \param _prosumer_data [in] pointer to Prosumer data * */ Prosumer_agent::Prosumer_agent(repast::AgentId &id, @@ -59,7 +58,6 @@ Prosumer_agent::Prosumer_agent(repast::AgentId &id, Profile* profiles, std::string &interpolation_type, struct data_props _d_props, - villas_node_config *_villas_config, Prosumer_data * _prosumer_data) : Agent(id, is_local, step_size, _behavior_type, _model_type, _prosumer_data->subtype, _d_props), prosumer_data(_prosumer_data) @@ -149,24 +147,25 @@ Prosumer_agent::Prosumer_agent(repast::AgentId &id, t_step, _d_props, prosumer_data); break; } +#ifdef WITH_VILLAS case CTRL_MQTT_TEST:{ behavior = new Mqtt_ref_prosumer_behavior(id_.id(), prosumer_data->type, id_.currentRank(), - prosumer_data->subtype, t_step, _d_props, _villas_config, prosumer_data); + prosumer_data->subtype, t_step, _d_props, prosumer_data); break; } case CTRL_MQTT_PINGPONG:{ behavior = new Mqtt_pingpong_prosumer_behavior(id_.id(), prosumer_data->type, id_.currentRank(), - prosumer_data->subtype, t_step, _d_props, _villas_config, prosumer_data); + prosumer_data->subtype, t_step, _d_props, prosumer_data); break; } case CTRL_ENSURE:{ behavior = new Ensure_prosumer_behavior(id_.id(), prosumer_data->type, id_.currentRank(), - prosumer_data->subtype, t_step, _d_props, _villas_config, prosumer_data); + prosumer_data->subtype, t_step, _d_props, prosumer_data); break; } case CTRL_MQTT_HIGHLOAD:{ behavior = new Mqtt_highload_prosumer_behavior(id_.id(), prosumer_data->type, id_.currentRank(), - prosumer_data->subtype, t_step, _d_props, _villas_config, prosumer_data); + prosumer_data->subtype, t_step, _d_props, prosumer_data); break; } case CTRL_DPSIM_COSIM_REF:{ @@ -179,6 +178,7 @@ Prosumer_agent::Prosumer_agent(repast::AgentId &id, t_step, _d_props, prosumer_data); break; } +#endif case CTRL_INTCOMM:{ behavior = new Refic_prosumer_behavior(id_.id(), prosumer_data->type, prosumer_data->subtype, t_step, _d_props, prosumer_data); @@ -196,10 +196,9 @@ Prosumer_agent::Prosumer_agent(repast::AgentId &id, /*! \brief Destructor of CHP_agent class * */ Prosumer_agent::~Prosumer_agent() { - delete behavior; delete prosumer_data; delete prosumer_model; - IO->finish_io(); + } /*! \brief advance a simulation step diff --git a/src/agents/slack_agent.cpp b/src/agents/slack_agent.cpp index cd6583cd2d59cf5652533838e679c567fc0284b1..e5b800304270b15f67a47c311d09e28862d52b22 100644 --- a/src/agents/slack_agent.cpp +++ b/src/agents/slack_agent.cpp @@ -18,11 +18,11 @@ #include "agents/slack_agent.h" #include "behavior/swarmgrid/swarm_slack_behavior.h" -#include "behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.h" +#include "behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.h" #include "behavior/reference/ref_slack_behavior.h" #include "behavior/ref_intcomm/refic_slack_behavior.h" #include "behavior/ensure/ensure_slack_behavior.h" -#include "behavior/dpsim_cosim/dpsim_cosim_slack_behavior.h" +#include "behavior/dpsim_cosim/dpsim_cosim_behavior.h" /*! \brief Constructor used for creation of copies of non-local agents * \param id [in] RepastHPC agent id @@ -41,7 +41,6 @@ Slack_agent::Slack_agent(repast::AgentId &id, bool is_local) : Agent(id, is_loca * \param _model_type [in] user selected type of el. models (0=static phasor models, 1=dynamic phasor models) * \param _subtype [in] subtype of the agent * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * */ Slack_agent::Slack_agent(repast::AgentId &id, bool is_local, @@ -53,10 +52,9 @@ Slack_agent::Slack_agent(repast::AgentId &id, int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, bool _ict_connected, bool _realtime -) : Slack_agent(id, is_local, step_size, _Vnom, _behavior_type, _model_type, _subtype, _d_props, _villas_config, _ict_connected, _realtime){ +) : Slack_agent(id, is_local, step_size, _Vnom, _behavior_type, _model_type, _subtype, _d_props, _ict_connected, _realtime){ // For cosimulation case, calculations do not use Vnom. Therefore model data voltage has to be set manually model_data.v_re = _Vre; @@ -85,7 +83,6 @@ Slack_agent::Slack_agent(repast::AgentId &id, * \param _model_type [in] user selected type of el. models (0=static phasor models, 1=dynamic phasor models) * \param _subtype [in] subtype of the agent * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * */ Slack_agent::Slack_agent(repast::AgentId &id, bool is_local, @@ -95,7 +92,6 @@ Slack_agent::Slack_agent(repast::AgentId &id, int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, bool _ict_connected, bool _realtime ) : Agent(id, is_local, step_size, _behavior_type, _model_type,_subtype, _d_props){ @@ -114,6 +110,7 @@ Slack_agent::Slack_agent(repast::AgentId &id, voltage.real(model_data.v_re); voltage.imag(model_data.v_im); + if(behavior_type != CTRL_DPSIM_COSIM_REF && behavior_type != CTRL_DPSIM_COSIM_SWARMGRIDX){ IO->log_info("Input params: Vnom="+ std::to_string(_Vnom) + "/ V_re="+ std::to_string(model_data.v_re) + "/ V_im=" + std::to_string(model_data.v_im)); @@ -133,23 +130,25 @@ Slack_agent::Slack_agent(repast::AgentId &id, behavior = new Swarm_slack_behavior(id_.id(), TYPE_SLACK_INT, _subtype, t_step, _d_props, &model_data); break; } +#ifdef WITH_VILLAS case CTRL_MQTT_TEST:{ behavior = new Ref_slack_behavior(id_.id(), TYPE_SLACK_INT, _subtype, t_step, _d_props); break; } case CTRL_ENSURE:{ behavior = new Ensure_slack_behavior(id_.id(), TYPE_SLACK_INT, id_.currentRank(), - _subtype, t_step, _d_props, _villas_config, &model_data); + _subtype, t_step, _d_props, &model_data); break; } case CTRL_DPSIM_COSIM_REF:{ - behavior = new Dpsim_cosim_slack_behavior(id_.id(), TYPE_SLACK_INT, id_.currentRank(), _subtype, t_step, _d_props, _villas_config, _realtime, true); + behavior = new Dpsim_cosim_behavior(id_.id(), TYPE_SLACK_INT, id_.currentRank(), _subtype, t_step, _d_props, _realtime, true); break; } case CTRL_DPSIM_COSIM_SWARMGRIDX:{ - behavior = new Swarm_dpsim_cosim_slack_behavior(id_.id(), TYPE_SLACK_INT, id_.currentRank(), _subtype, t_step, _d_props, &model_data, _villas_config, _realtime, true); + behavior = new Dpsim_cosim_swarm_behavior(id_.id(), TYPE_SLACK_INT, id_.currentRank(), _subtype, t_step, _d_props, &model_data, _realtime, true); break; } +#endif case CTRL_INTCOMM:{ behavior = new Refic_slack_behavior(id_.id(), TYPE_SLACK_INT, _subtype, t_step, _d_props); break; @@ -161,14 +160,6 @@ Slack_agent::Slack_agent(repast::AgentId &id, } } -/*! \brief Destructor of Slack_agent class - * */ -Slack_agent::~Slack_agent() { - delete behavior; - IO->finish_io(); - -} - /*! \brief advance a simulation step * */ void Slack_agent::step() { @@ -198,10 +189,12 @@ void Slack_agent::step() { first_step = false; } +#ifdef WITH_VILLAS // needed to prevent distaix to report to dpsim after last timestep if(behavior_type == CTRL_DPSIM_COSIM_REF || behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX) { get_new_vals = true; } +#endif } /*! \brief calculation of model for a simulation step @@ -240,72 +233,38 @@ bool Slack_agent::do_backward_sweep( if(next_action_expected == BACKWARD_SWEEP && all_next_nodes_finished_BACKWARD) { IO->log_info("\tSLACK in BACKWARD SWEEP: "); +#ifdef WITH_VILLAS // get_new_vals makes sure report_to_superior grid is only executed once per timestep. // Therefore it implicitly avoids message exchange when no slack convergence is reached if ((behavior_type == CTRL_DPSIM_COSIM_REF || behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX) && get_new_vals) { - std::list incoming_villas_messages; - - if (behavior_type == CTRL_DPSIM_COSIM_REF) { - // Dynamically cast the behavior of the correct behavior type to enable calling of behavior specific methods - auto *cosim_behavior = dynamic_cast(behavior); - - Dpsim_cosim_msg out_msg; - - out_msg.value->real((float) -current.real()); - out_msg.value->imag((float) -current.imag()); - - cosim_behavior->report_to_superior_grid(out_msg, &incoming_villas_messages); - } else if (behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX) { - auto *cosim_behavior = dynamic_cast(behavior); - Dpsim_cosim_msg out_msg; + double current_tick = repast::RepastProcess::instance()->getScheduleRunner().currentTick(); + std::complex new_voltage; - out_msg.value->real((float) -current.real()); - out_msg.value->imag((float) -current.imag()); - - cosim_behavior->report_to_superior_grid(out_msg, &incoming_villas_messages); - } - - // TODO: - // As DPsim might simulate much faster than DistAIX, there can be multiple messages in the queue - // Find some strategy what to do: Currently the messages will be simply popped from front - - Dpsim_cosim_msg in_msg; - if (!incoming_villas_messages.empty()) { - in_msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); - // set pointer of data to members - in_msg.set_pointers(); - - incoming_villas_messages.pop_front(); + if (behavior_type == CTRL_DPSIM_COSIM_REF){ + auto *cosim_behavior = dynamic_cast(behavior); + new_voltage = cosim_behavior->get_new_voltage_values(current, model_data.v_re, model_data.i_im, current_tick); } else { - if (realtime) { - IO->log_info("[REALTIME] No new values at socket..."); - } else { - IO->log_info( - "ERROR IN BACKWARD SWEEP! BUSY WAITING RETURNED BUT NO RESPONSE FROM DPSIM COULD BE READ"); - } - - IO->log_info("\tTake old value again..."); - - in_msg.value->real((float) model_data.v_re); - in_msg.value->imag((float) model_data.i_im); + // CTRL_DPSIM_COSIM_SWARMGRIDX + auto *cosim_behavior = dynamic_cast(behavior); + new_voltage = cosim_behavior->get_new_voltage_values(current, model_data.v_re, model_data.i_im, current_tick); } voltage_prev = voltage; - IO->log_info("V_re = " + std::to_string(in_msg.value->real())); - IO->log_info("V_im = " + std::to_string(in_msg.value->imag())); - model_data.v_re = in_msg.value->real(); - model_data.v_im = in_msg.value->imag(); + IO->log_info("V_re = " + std::to_string(new_voltage.real())); + IO->log_info("V_im = " + std::to_string(new_voltage.imag())); + model_data.v_re = new_voltage.real(); + model_data.v_im = new_voltage.imag(); IO->log_info("\t Set model_data.v_re = " + std::to_string(model_data.v_re)); IO->log_info("\t Set model_data.v_im = " + std::to_string(model_data.v_im)); - voltage.real(in_msg.value->real()); - voltage.imag(in_msg.value->imag()); + voltage.real(new_voltage.real()); + voltage.imag(new_voltage.imag()); get_new_vals = false; } - +#endif current.imag(0.0); current.real(0.0); diff --git a/src/agents/transformer_agent.cpp b/src/agents/transformer_agent.cpp index de991889acc0e8db13805b83cdfaa7015656e584..cf461435822cc4d12e23d75349eefea41f942aad 100644 --- a/src/agents/transformer_agent.cpp +++ b/src/agents/transformer_agent.cpp @@ -39,7 +39,6 @@ Transformer_agent::Transformer_agent(repast::AgentId &id, bool is_local) : Agent * \param _model_type [in] user selected type of el. models (0=static phasor models, 1=dynamic phasor models) * \param _subtype [in] subtype of the agent * \param _d_props [in] properties of logging and result saving - * \param _villas_config [in] configuration for villas node * \param _Vnom1 [in] voltage at primary side in V * \param _Vnom2 [in] voltage at secondary side in V * \param R [in] resistance in Ohm @@ -57,7 +56,6 @@ Transformer_agent::Transformer_agent(repast::AgentId &id, int &_model_type, std::string &_subtype, struct data_props _d_props, - villas_node_config *_villas_config, double _Vnom1, double _Vnom2, double R, @@ -106,21 +104,22 @@ Transformer_agent::Transformer_agent(repast::AgentId &id, behavior = new Swarm_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT, _subtype, t_step, _d_props, &substation_data); break; } +#ifdef WITH_VILLAS case CTRL_MQTT_TEST:{ //behavior = new Ref_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT, _subtype, t_step, logging, &substation_data, &substation_data); - behavior = new Mqtt_ref_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, _villas_config, &substation_data); + behavior = new Mqtt_ref_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, &substation_data); break; } case CTRL_MQTT_PINGPONG:{ - behavior = new Mqtt_pingpong_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, _villas_config, &substation_data); + behavior = new Mqtt_pingpong_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, &substation_data); break; } case CTRL_ENSURE:{ - behavior = new Ensure_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, _villas_config, &substation_data); + behavior = new Ensure_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, &substation_data); break; } case CTRL_MQTT_HIGHLOAD:{ - behavior = new Mqtt_highload_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, _villas_config, &substation_data); + behavior = new Mqtt_highload_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT,id_.currentRank(), _subtype, t_step, _d_props, &substation_data); break; } case CTRL_DPSIM_COSIM_REF:{ @@ -131,6 +130,7 @@ Transformer_agent::Transformer_agent(repast::AgentId &id, behavior = new Swarm_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT, _subtype, t_step, _d_props, &substation_data); break; } +#endif case CTRL_INTCOMM:{ behavior = new Refic_substation_behavior(id_.id(), TYPE_TRANSFORMER_INT, _subtype, t_step, _d_props, &substation_data); break; @@ -153,8 +153,7 @@ Transformer_agent::Transformer_agent(repast::AgentId &id, /*! \brief Destructor of Transformer_agent class * */ Transformer_agent::~Transformer_agent() { - delete behavior; - IO->finish_io(); + delete transformer_model; } /*! \brief advance a simulation step diff --git a/src/behavior/agent_behavior.cpp b/src/behavior/agent_behavior.cpp index 6073363a27d16e681891e7685fb2908694016da6..f4f3582f6f2d3187222825ba742ac894666c1036 100644 --- a/src/behavior/agent_behavior.cpp +++ b/src/behavior/agent_behavior.cpp @@ -16,7 +16,9 @@ *********************************************************************************/ #include "behavior/agent_behavior.h" -#include "villas_interface/villas_interface.h" +#ifdef WITH_VILLAS + #include "villas_interface.h" +#endif /*! \brief Constructor used for creation of agent behavior * \param _id [in] RepastHPC agent id @@ -33,7 +35,9 @@ Agent_behavior::Agent_behavior(int _id, int _type, std::string _subtype, double& msg_received = 0; outgoing_messages.clear(); incoming_messages.clear(); +#ifdef WITH_VILLAS villas_interface = nullptr; +#endif struct data_props d_props = _d_props; //change name of result subfolder @@ -48,6 +52,22 @@ Agent_behavior::Agent_behavior(int _id, int _type, std::string _subtype, double& * \brief Destroy the Agent_behavior::Agent_behavior object */ Agent_behavior::~Agent_behavior() { + IO->log_info("Deleting behavior"); +#ifdef WITH_VILLAS + if (villas_interface){ + + delete villas_interface; + + // wait 1ms for all disconnections to complete + struct timespec t{}; + t.tv_sec = 0; + t.tv_nsec = 1000000; + nanosleep(&t, nullptr); + IO->log_info("villas interface destruction successful"); + } +#endif + IO->finish_io(); + delete IO; } /*! \brief update time (to be called after every time step) @@ -139,34 +159,34 @@ unsigned int Agent_behavior::get_msg_received() { return msg_received; } - -int Agent_behavior::init_villas_interface(villas_node_config *_villas_config, std::vector &meta) { +#ifdef WITH_VILLAS +/*! + * \brief initialization of villas interface (optional) + * \param custom_param_json_string customized json parameters for VILLASnode as string + */ +int Agent_behavior::init_villas_interface(std::string custom_param_json_string) { //init and start villas node interface IO->log_info("Setting up villas interface"); try{ - villas_interface = new Villas_interface(_villas_config, IO, "agent_" + std::to_string(id), meta); - //villas_interface->init(); - villas_interface->start(); + villas_interface = new Villas_interface(custom_param_json_string); } catch (std::runtime_error &ex) { - IO->log_info("Caught exception: " + std::string(ex.what())); + IO->log_info("Caught exception upon creating villas interface: " + std::string(ex.what())); return -1; } return 0; } - -int Agent_behavior::destroy_villas_interface() { - if(villas_interface !=nullptr) { - //init and start villas node interface - IO->log_info("Destroying villas interface"); - try { - villas_interface->stop(); - villas_interface->destroy(); - } catch (std::runtime_error &ex) { - IO->log_info("Caught exception: " + std::string(ex.what())); - return -1; - } - delete villas_interface; +/*! + * \brief sending function for mqtt messages + * \param msg message to be sent + */ +void Agent_behavior::send_villas_msg(Villas_message &msg) { + int ret = villas_interface->send(msg); + if (ret < 0){ + IO->log_info("ERROR sending villas message: " + msg.toString() + " Villas_interface::send() returned with " + std::to_string(ret)); + std::cerr << "ERROR sending villas message: " << msg.toString() << " from agent " << id << " Villas_interface::send() returned with " << ret << std::endl; + MPI_Abort(MPI_COMM_WORLD, -9); } - return 0; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/behavior/dpsim_cosim/dpsim_cosim_behavior.cpp b/src/behavior/dpsim_cosim/dpsim_cosim_behavior.cpp index b367aa6e6100ddaecfa7e13dfa13385ff67f56f4..50cae7e691b172b38a592020d7068faa009222f6 100644 --- a/src/behavior/dpsim_cosim/dpsim_cosim_behavior.cpp +++ b/src/behavior/dpsim_cosim/dpsim_cosim_behavior.cpp @@ -14,9 +14,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/dpsim_cosim/dpsim_cosim_behavior.h" -#include "villas_interface/villas_interface.h" + + +double Dpsim_cosim_behavior::stop_at; +std::string Villas_interface::type; /*! \brief constructor * \param _id unique ID of agent @@ -26,50 +29,191 @@ * \param logging indicates if agents logs locally * */ -Dpsim_cosim_behavior::Dpsim_cosim_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, - struct data_props _d_props, villas_node_config * _villas_config) - : Agent_behavior(_id, _type, _subtype, step_size, _d_props) +Dpsim_cosim_behavior::Dpsim_cosim_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, + struct data_props _d_props, bool _realtime, bool _sync) + : Agent_behavior(_id, _type, _subtype, _step_size, _d_props) { - vnconfig = _villas_config; IO->init_logging(); + sender = _id; + step_size = _step_size; + realtime = _realtime; + sync = _sync; } Dpsim_cosim_behavior::~Dpsim_cosim_behavior() { IO->log_info("Number of sent messages: " + std::to_string(numOfSentMessages)); IO->log_info("Number of received messages: " + std::to_string(numOfReceivedMessages)); - //destroy_villas_interface is called in agent method - IO->finish_io(); } + +/*! \brief Initialize the agent behavior + * \param components_ad_nodes [in] vector saving a list of connceted components for each node + * \param connected_nodes [in] vector saving a list of connected nodes for each node + * \param components_file [in] data contained in scenario components input file (integers) + * \param subtypes_file [in] subtypes contained in scenario components input file (strings) + * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) + * */ +int Dpsim_cosim_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) { + // create custom params json string + std::string custom_param_json_string = get_json_config_string(id); + IO->log_info("VILLASnode JSON custom config is: " + custom_param_json_string); + if(custom_param_json_string.empty()){ + IO->log_info("ERROR: '" + Villas_interface::type + "' is no valid type for cosim behavior..."); + return -1; + } + + // Initialize villas interface + IO->log_info("Initializing villas interface..."); + int ret = init_villas_interface(custom_param_json_string); + if (ret) { + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); + + if(sync){ + synchronize_with_remote(); + } + + return 0; + +} + + +std::string Dpsim_cosim_behavior::get_json_config_string(int agent_id) { + std::string custom_param_json_string = "{}"; + if(Villas_interface::type == "nanomsg"){ + //create_endpoints(vnconfig, std::to_string(sender)); + custom_param_json_string = "{\"name\": \"agent_" + std::to_string(agent_id) + "\"}"; + } + else if(Villas_interface::type == "mqtt") { + + custom_param_json_string = "{ \"in\": {\"subscribe\": \"dpsim->dist\"}, \"out\": {\"publish\": \"dist->dpsim\"}, \"name\": \"agent_" + std::to_string(agent_id) + "\"}"; + //vnconfig->type_config.mqtt_conf->subscribe = "dpsim->dist"; + //vnconfig->type_config.mqtt_conf->publish = "dist->dpsim"; + } + else { + return ""; + } + return custom_param_json_string; +} + +/*! \brief Slack agent has nothing to do for cosim behavior simulation step (=reference behavior of slack) + * */ +void Dpsim_cosim_behavior::execute_agent_behavior() { + +} + + /*! \brief process all messages that have been received since the last time step and call protocol - * specific process function + * specific process function; for this behavior this case does not happen * */ +/*void Dpsim_cosim_behavior::process_incoming_messages() { + +}*/ + +void Dpsim_cosim_behavior::synchronize_with_remote(){ + + bool remove_msg_overhead = false; -void Dpsim_cosim_behavior::process_incoming_messages() { + IO->log_info("###### Start synchronization with remote..."); + Dpsim_cosim_msg out_msg(std::complex(0,0)); std::list incoming_villas_messages; - villas_interface->receive_messages(incoming_villas_messages); + IO->log_info("Waiting for answer..."); + busy_receive_msg(&incoming_villas_messages); + send_msg(out_msg); - while (!incoming_villas_messages.empty()) { - Dpsim_cosim_msg dpsim_cosim_msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); - // set pointers of data to members - dpsim_cosim_msg.set_pointers(); - IO->log_info("\tReceived message: " + dpsim_cosim_msg.get_message_output()); + // process incoming message + if (!incoming_villas_messages.empty()) { + if(incoming_villas_messages.size() > 1){ + IO->log_info("WARNING: More than one sync message received... (" + + std::to_string(incoming_villas_messages.size()) + ")"); + } + auto in_msg = incoming_villas_messages.front(); - this->process_dpsim_cosim_msg(dpsim_cosim_msg); incoming_villas_messages.pop_front(); + + IO->log_info("Answer received..."); + IO->log_info("\tSync.in_re = " + std::to_string(in_msg.data.front().z.real())); + IO->log_info("\tSync.in_im = " + std::to_string(in_msg.data.front().z.imag())); + } + else { + IO->log_info("ERROR IN SYNCHRONIZE_WITH_REMOTE! BUSY WAITING RETURNED BUT NO RESPONSE COULD BE READ"); + } + + + + if (remove_msg_overhead) { + IO->log_info("Additional removal of second synchronization message of dpsim triggered..."); + IO->log_info("Be careful with this option, as the removal of the CORRECT message cannot be guaranteed..."); + + IO->log_info("Waiting for answer..."); + IO->log_info("Wait 5secs before reading socket again..."); + sleep(5); + busy_receive_msg(&incoming_villas_messages); + + // process incoming message + if (!incoming_villas_messages.empty()) { + if(incoming_villas_messages.size() > 1){ + IO->log_info("WARNING: More than one sync message received... (" + + std::to_string(incoming_villas_messages.size()) + ")"); + } + auto in_msg = incoming_villas_messages.front(); + + incoming_villas_messages.pop_front(); + + IO->log_info("Answer received..."); + IO->log_info("\tSync2.in_re = " + std::to_string(in_msg.data.front().z.real())); + IO->log_info("\tSync2.in_im = " + std::to_string(in_msg.data.front().z.imag())); + } } } -/*! - * \brief sending function for nanomsg messages - * \param msg message to be sent - */ -void Dpsim_cosim_behavior::send_villas_msg(Villas_message &msg) { - villas_interface->send_message(msg); + + + +/*! \brief global initializations (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Dpsim_cosim_behavior::global_init(std::string config_file_path, double stop_at_init, int rank) { + /*init the global instance and start the node type*/ + Dpsim_cosim_behavior::stop_at = stop_at_init; + return Villas_interface::start_node_type(config_file_path, rank); +} + +/*! \brief global cleanup (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Dpsim_cosim_behavior::global_cleanup() { + return Villas_interface::stop_node_type(); } +/*! \brief global actions (process-wide) for behavior in step method of model + * \return value for stop_at in process + * */ +double Dpsim_cosim_behavior::global_step(double process_stop_at, int slack_rank, int world_size) { + + // return the stop_at variable of the rank with the slack agent to set the scheduler in all processes to this value + + if (world_size > 1 ){ + MPI_Bcast(&Dpsim_cosim_behavior::stop_at, 1, MPI_DOUBLE, slack_rank, MPI_COMM_WORLD); + return Dpsim_cosim_behavior::stop_at; + }else { + return process_stop_at; + } +} + +/* void Dpsim_cosim_behavior::create_endpoints(villas_node_config * _vnconfig, std::string agent_id) { std::list communication_patterns; @@ -87,3 +231,122 @@ void Dpsim_cosim_behavior::create_endpoints(villas_node_config * _vnconfig, std: } + */ + + + +void Dpsim_cosim_behavior::send_msg(Dpsim_cosim_msg message) { + numOfSentMessages++; + + IO->log_info("\tSend message: " + message.toString()); + send_villas_msg(message); +} + +void Dpsim_cosim_behavior::receive_message(std::list *incoming_villas_messages) { + numOfReceivedMessages++; + + bool single_read = false; + if (Villas_interface::type == "nanomsg"){ + single_read = true; + } + + villas_interface->receive(*incoming_villas_messages, 100, single_read); + if(!incoming_villas_messages->empty()) { + IO->log_info("Message received..." + std::to_string(incoming_villas_messages->size())); + } +} + +int Dpsim_cosim_behavior::busy_receive_msg(std::list *incoming_villas_messages) { + bool message_removal = true; + numOfReceivedMessages++; + // TODO: Do not cancel in first step!!... + auto start = std::chrono::steady_clock::now(); + while(incoming_villas_messages->empty()) { + // If timeout reached, return 1 to signalize early simulation stop + if (std::chrono::duration_cast(std::chrono::steady_clock::now()-start).count() >= timeout) + return 1; + + bool single_read = false; + if (Villas_interface::type == "nanomsg"){ + single_read = true; + } + + villas_interface->receive(*incoming_villas_messages, 100, single_read); + } + if(!incoming_villas_messages->empty()) { + IO->log_info("Message received..."); + + if(incoming_villas_messages->size() > 1 && message_removal){ + IO->log_info("More than one message received!"); + + auto it = incoming_villas_messages->begin(); + std::advance(it, incoming_villas_messages->size() - 1); + incoming_villas_messages->erase(incoming_villas_messages->begin(), it); // Complexity linear with number of erased elements + + IO->log_info("Reduced down to: " + std::to_string(incoming_villas_messages->size())); + } + } + + // if(first_step) + // first_step = false; + // auto stop = std::chrono::steady_clock::now(); + // IO->log_info("Time in busy_receive_msg() = " + std::to_string(std::chrono::duration_cast(stop-start).count())); + return 0; +} + +void Dpsim_cosim_behavior::report_to_superior_grid(Dpsim_cosim_msg message, std::list *incoming_villas_messages, double current_tick) { + + IO->log_info("###### Execute dpsim_cosim behavior... "); + send_msg(message); + + if(realtime){ + IO->log_info("[REALTIME] Try to read new message..."); + receive_message(incoming_villas_messages); + } + else { + IO->log_info("Wait until message arrives..."); + int ret = busy_receive_msg(incoming_villas_messages); + if(ret == 1) { + // early simulation stop signalized + Dpsim_cosim_behavior::stop_at = current_tick; + std::cout << std::endl << "Cosimulation-timeout reached! Stopping simulation..." << std::endl; + } + } +} + +std::complex Dpsim_cosim_behavior::get_new_voltage_values(std::complex ¤t, double &v_re_old, double &v_im_old, double current_tick) { + + std::list incoming_villas_messages; + + Dpsim_cosim_msg out_msg (std::complex ((float) -current.real(), (float) -current.imag())); + + this->report_to_superior_grid(out_msg, &incoming_villas_messages, current_tick); + + // TODO: + // As DPsim might simulate much faster than DistAIX, there can be multiple messages in the queue + // Find some strategy what to do: Currently the messages will be simply popped from front + + double value_real, value_imag; + if (!incoming_villas_messages.empty()) { + auto in_msg = incoming_villas_messages.front(); + value_real = in_msg.data.front().z.real(); + value_imag = in_msg.data.front().z.imag(); + incoming_villas_messages.pop_front(); + } else { + if (realtime) { + IO->log_info("[REALTIME] No new values at socket..."); + } else { + IO->log_info( + "ERROR IN BACKWARD SWEEP! BUSY WAITING RETURNED BUT NO RESPONSE FROM DPSIM COULD BE READ"); + } + + IO->log_info("\tTake old voltage value again..."); + + value_real = v_re_old; + value_imag = v_im_old; + } + + return {value_real, value_imag}; + +} +#endif \ No newline at end of file diff --git a/src/behavior/dpsim_cosim/dpsim_cosim_message.cpp b/src/behavior/dpsim_cosim/dpsim_cosim_message.cpp index 9d1f3c4087c9db60c568d619ab4d1a66a35119d6..150b763b57f6035da25bda4b54d527ed55815b2f 100644 --- a/src/behavior/dpsim_cosim/dpsim_cosim_message.cpp +++ b/src/behavior/dpsim_cosim/dpsim_cosim_message.cpp @@ -14,71 +14,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/dpsim_cosim/dpsim_cosim_message.h" -#include - -std::vector Dpsim_cosim_msg::dpsim_cosim_message_meta = std::vector(); -bool Dpsim_cosim_msg::meta_initialized = false; - -Dpsim_cosim_msg::Dpsim_cosim_msg() : Villas_message() { - value = nullptr; - init_message(std::complex(0.0,0.0)); - -} -Dpsim_cosim_msg::Dpsim_cosim_msg(Villas_message &msg) : Villas_message() { - data = msg.data; - length = msg.length; - -} - -void Dpsim_cosim_msg::set_pointers() { - value = &(data[0].z); +Dpsim_cosim_msg::Dpsim_cosim_msg(std::complex value) : Villas_message() { + Data_element d; + d.z = value; + data.push_back(d); + data_types.push_back(VILLASMSG_COMPLEX); + length = data.size(); } - -void Dpsim_cosim_msg::init_message(std::complex _value) { - - // add all data and meta elements of this message type - Data_element value_data; - value_data.z = _value; - add_element(value_data, VILLAS_DATA_TYPE_COMPLEX); - - // set the pointers of the message to the corresponding fields in data - set_pointers(); - -} - -void Dpsim_cosim_msg::init_meta() { - // returns immediately if static meta information has already been initialized for this message type - // initialize meta info only once - if(!Dpsim_cosim_msg::meta_initialized) { - Dpsim_cosim_msg::meta_initialized = true; - Dpsim_cosim_msg::dpsim_cosim_message_meta.clear(); - - //Data values - Meta_infos value_meta; - value_meta.name = "value_complex"; - value_meta.unit = "value_complex of this message"; - value_meta.type = VILLAS_DATA_TYPE_COMPLEX; - Dpsim_cosim_msg::dpsim_cosim_message_meta.push_back(value_meta); - - } -} - -/*! -* \brief Writes the content of a message to a string for debugging -* \return Message content as string -* */ - -std::string Dpsim_cosim_msg::get_message_output() { - std::stringstream temp; - std::string output; - - temp << "Time: " << time_sec << std::endl - << " Value_Re: " << value->real() << std::endl - << " Value_Im: " << value->imag(); - - output = temp.str(); - return output; -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/behavior/dpsim_cosim/dpsim_cosim_slack_behavior.cpp b/src/behavior/dpsim_cosim/dpsim_cosim_slack_behavior.cpp deleted file mode 100644 index f6d1dc61d40e16b2cab183adf533dafa272e89f6..0000000000000000000000000000000000000000 --- a/src/behavior/dpsim_cosim/dpsim_cosim_slack_behavior.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/** - * This file is part of DistAIX - * - * 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 . - *********************************************************************************/ - -#include "behavior/dpsim_cosim/dpsim_cosim_slack_behavior.h" -#include "villas_interface/villas_interface.h" -#include -#include - -/*! \brief Constructor used for creation of DF reference behavior - * \param _id [in] RepastHPC agent id - * \param _type [in] component type of the agent - * \param _subtype [in] component subtype of the agent - * \param step_size [in] size of a simulation step in seconds - * \param logging [in] indicates if agents logs locally - * */ - -Dpsim_cosim_slack_behavior::Dpsim_cosim_slack_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, - struct data_props _d_props, villas_node_config * _villas_config, bool _realtime, bool _sync) - : Dpsim_cosim_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config) -{ - // this->sender = _id; - // this->step_size = step_size; - // this->realtime = _realtime; - sender = _id; - step_size = _step_size; - realtime = _realtime; - sync = _sync; - -} - - -void Dpsim_cosim_slack_behavior::synchronize_with_remote(){ - - bool remove_msg_overhead = false; - - IO->log_info("###### Start synchronization with remote..."); - Dpsim_cosim_msg out_msg, in_msg; - std::list incoming_villas_messages; - - IO->log_info("Waiting for answer..."); - busy_receive_msg(&incoming_villas_messages); - send_msg(out_msg); - - // process incoming message - if (!incoming_villas_messages.empty()) { - if(incoming_villas_messages.size() > 1){ - IO->log_info("WARNING: More than one sync message received... (" - + std::to_string(incoming_villas_messages.size()) + ")"); - } - in_msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); - // set pointer of data to members - in_msg.set_pointers(); - - incoming_villas_messages.pop_front(); - - IO->log_info("Answer received..."); - IO->log_info("\tSync.in_re = " + std::to_string(in_msg.value->real())); - IO->log_info("\tSync.in_im = " + std::to_string(in_msg.value->imag())); - } - else { - IO->log_info("ERROR IN SYNCHRONIZE_WITH_REMOTE! BUSY WAITING RETURNED BUT NO RESPONSE COULD BE READ"); - } - - - - if (remove_msg_overhead) { - IO->log_info("Additional removal of second synchronization message of dpsim triggered..."); - IO->log_info("Be careful with this option, as the removal of the CORRECT message cannot be guaranteed..."); - - IO->log_info("Waiting for answer..."); - IO->log_info("Wait 5secs before reading socket again..."); - sleep(5); - busy_receive_msg(&incoming_villas_messages); - - // process incoming message - if (incoming_villas_messages.size() >= 1) { - if(incoming_villas_messages.size() > 1){ - IO->log_info("WARNING: More than one sync message received... (" - + std::to_string(incoming_villas_messages.size()) + ")"); - } - in_msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); - // set pointer of data to members - in_msg.set_pointers(); - - incoming_villas_messages.pop_front(); - - IO->log_info("Answer received..."); - IO->log_info("\tSync2.in_re = " + std::to_string(in_msg.value->real())); - IO->log_info("\tSync2.in_im = " + std::to_string(in_msg.value->imag())); - } - } - -} - -/*! \brief Initialize the agent behavior - * \param components_ad_nodes [in] vector saving a list of connceted components for each node - * \param connected_nodes [in] vector saving a list of connected nodes for each node - * \param components_file [in] data contained in scenario components input file (integers) - * \param subtypes_file [in] subtypes contained in scenario components input file (strings) - * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) - * */ - -int Dpsim_cosim_slack_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file) { - // initialize meta information for all message types used in this behavior - Dpsim_cosim_msg::init_meta(); - if(vnconfig->type_name == "nanomsg"){ - IO->log_info("Create Endpoints..."); - create_endpoints(vnconfig, std::to_string(sender)); - } - else if(vnconfig->type_name == "mqtt") { - IO->log_info("Set connection parameters..."); - vnconfig->type_config.mqtt_conf->subscribe = "dpsim->dist"; - vnconfig->type_config.mqtt_conf->publish = "dist->dpsim"; - } - else { - IO->log_info("ERROR: '" + vnconfig->type_name + "' is no valid type for cosim behavior..."); - } - - // Initialize villas interface (important: after init of message meta info!) - IO->log_info("Init VILLAS interface..."); - int ret = init_villas_interface(vnconfig, Dpsim_cosim_msg::dpsim_cosim_message_meta); - if (ret) { - return ret; - } - - if(sync){ - synchronize_with_remote(); - } - - return 0; - - - -} - -/*! \brief Slack agent has nothing to do in reference behavior - * */ -void Dpsim_cosim_slack_behavior::execute_agent_behavior() { - -} - -void Dpsim_cosim_slack_behavior::report_to_superior_grid(Dpsim_cosim_msg message, std::list *incoming_villas_messages) { - - IO->log_info("###### Execute dpsim_cosim behavior... "); - send_msg(message); - - if(realtime){ - IO->log_info("[REALTIME] Try to read new message..."); - receive_message(incoming_villas_messages); - } - else { - IO->log_info("Wait until message arrives..."); - int ret = busy_receive_msg(incoming_villas_messages); - if(ret == 1) { - // early simulation stop signalized - vnconfig->stop_at = repast::RepastProcess::instance()->getScheduleRunner().currentTick(); - std::cout << std::endl << "Cosimulation-timeout reached! Stopping simulation..." << std::endl; - } - } -} - -void Dpsim_cosim_slack_behavior::send_msg(Dpsim_cosim_msg message) { - numOfSentMessages++; - - IO->log_info("\tSend message: " + message.get_message_output()); - send_villas_msg(message); -} - -// void Dpsim_cosim_slack_behavior::receive_msg() { -// numOfReceivedMessages++; -// IO->log_info("Reading message..."); -// std::list incoming_villas_messages; -// villas_interface->receive_messages(incoming_villas_messages); - -// while (!incoming_villas_messages.empty()) { -// Dpsim_cosim_msg msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); -// // set pointer of data to members -// msg.set_pointers(); -// IO->log_info("\tReceived message: " + msg.get_message_output()); - -// incoming_villas_messages.pop_front(); -// } -// } - -void Dpsim_cosim_slack_behavior::receive_message(std::list *incoming_villas_messages) { - numOfReceivedMessages++; - - villas_interface->receive_messages(*incoming_villas_messages); - if(!incoming_villas_messages->empty()) { - IO->log_info("Message received..." + std::to_string(incoming_villas_messages->size())); - } -} - -int Dpsim_cosim_slack_behavior::busy_receive_msg(std::list *incoming_villas_messages) { - bool message_removal = true; - numOfReceivedMessages++; - // TODO: Do not cancel in first step!!... - auto start = std::chrono::steady_clock::now(); - while(incoming_villas_messages->empty()) { - // If timeout reached, return 1 to signalize early simulation stop - if (std::chrono::duration_cast(std::chrono::steady_clock::now()-start).count() >= timeout) - return 1; - - villas_interface->receive_messages(*incoming_villas_messages); - } - if(!incoming_villas_messages->empty()) { - IO->log_info("Message received..."); - - if(incoming_villas_messages->size() > 1 && message_removal){ - IO->log_info("More than one message received!"); - - auto it = incoming_villas_messages->begin(); - std::advance(it, incoming_villas_messages->size() - 1); - incoming_villas_messages->erase(incoming_villas_messages->begin(), it); // Complexity linear with number of erased elements - - IO->log_info("Reduced down to: " + std::to_string(incoming_villas_messages->size())); - } - } - - // if(first_step) - // first_step = false; - // auto stop = std::chrono::steady_clock::now(); - // IO->log_info("Time in busy_receive_msg() = " + std::to_string(std::chrono::duration_cast(stop-start).count())); - return 0; -} - -void Dpsim_cosim_slack_behavior::process_dpsim_cosim_msg(Dpsim_cosim_msg &msg) { - -} diff --git a/src/behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.cpp b/src/behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a58f26c167875e09de254fd60b68a343a867d6b1 --- /dev/null +++ b/src/behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.cpp @@ -0,0 +1,56 @@ +/** + * This file is part of DistAIX + * + * 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 . + *********************************************************************************/ +#ifdef WITH_VILLAS +#include "behavior/dpsim_cosim/dpsim_cosim_swarm_behavior.h" +#include "behavior/dpsim_cosim/dpsim_cosim_behavior.h" + + +Dpsim_cosim_swarm_behavior::Dpsim_cosim_swarm_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, struct data_props _d_props, + Slack_data * _slack_data, bool _realtime, bool _sync) + : Swarm_slack_behavior(_id, _type, _subtype, _step_size, _d_props, _slack_data) +{ + + dprops_dpsim_cosim = _d_props; + dprops_dpsim_cosim.log.path_log_file = "runlog/behavior/agent_" + std::to_string(_id) + "_dpsim_cosim.log"; + dpsim_cosim = new Dpsim_cosim_behavior(_id, _type, _rank, _subtype, _step_size, dprops_dpsim_cosim, _realtime, _sync); +} + +Dpsim_cosim_swarm_behavior::~Dpsim_cosim_swarm_behavior() { + + delete dpsim_cosim; +} + +int Dpsim_cosim_swarm_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) { + + int ret = Swarm_slack_behavior::initialize_agent_behavior(components_at_nodes, connected_nodes, components_file, subtypes_file, el_grid_file); + if (ret){ + return ret; + } + ret = dpsim_cosim->initialize_agent_behavior(components_at_nodes, connected_nodes, components_file, subtypes_file, el_grid_file); + return ret; +} + + +std::complex Dpsim_cosim_swarm_behavior::get_new_voltage_values(std::complex ¤t, double &v_re_old, + double &v_im_old, double current_tick) { + return dpsim_cosim->get_new_voltage_values(current, v_re_old, v_im_old, current_tick); +} +#endif \ No newline at end of file diff --git a/src/behavior/ensure/ensure_behavior.cpp b/src/behavior/ensure/ensure_behavior.cpp index cc76f0bc971fdca4e2edb85bd11b2025d73ff624..f10ba705e1af82fc6a095e2ff7ecd8ecf10006b2 100644 --- a/src/behavior/ensure/ensure_behavior.cpp +++ b/src/behavior/ensure/ensure_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/ensure/ensure_behavior.h" -#include "villas_interface/villas_interface.h" #include "model/time_measurement.h" /*! \brief constructor @@ -27,11 +26,11 @@ * \param logging indicates if agents logs locally * */ Ensure_behavior::Ensure_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, - struct data_props _d_props, villas_node_config * _villas_config) + struct data_props _d_props) : Agent_behavior(_id, _type, _subtype, step_size, _d_props) { - vnconfig = _villas_config; + //vnconfig = _villas_config; if(_type == TYPE_DF_INT) { std::string path = "runlog/behavior/agent_DF" + std::to_string(_rank) + ".log"; @@ -44,9 +43,19 @@ Ensure_behavior::Ensure_behavior(int _id, int _type, int _rank, std::string _sub } -Ensure_behavior::~Ensure_behavior(){ - //destroy_villas_interface is called in agent method - IO->finish_io(); +/*! \brief global initializations (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Ensure_behavior::global_init(std::string config_file_path, int rank) { + /*init the global instance and start the node type*/ + return Villas_interface::start_node_type(config_file_path, rank); +} + +/*! \brief global cleanup (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Ensure_behavior::global_cleanup() { + return Villas_interface::stop_node_type(); } /*! \brief process all messages that have been received since the last time step and call protocol @@ -56,13 +65,12 @@ void Ensure_behavior::process_incoming_messages() { std::list incoming_villas_messages; - villas_interface->receive_messages(incoming_villas_messages); + villas_interface->receive(incoming_villas_messages, 1000, false); while (!incoming_villas_messages.empty()) { - Ensure_msg msg = (Ensure_msg) incoming_villas_messages.front(); - //set pointers of data to members - msg.set_pointers(); - IO->log_info("\tReceived message: " + msg.get_message_output()); + auto msg = incoming_villas_messages.front(); + + IO->log_info("\tReceived message: " + msg.toString()); this->process_ensure_msg(msg); incoming_villas_messages.pop_front(); @@ -83,17 +91,25 @@ int Ensure_behavior::initialize_agent_behavior(std::vector *subtypes_file, boost::multi_array *el_grid_file) { - - //initialize meta information for all message types used in this behavior - Ensure_msg::init_meta(); - //prosumers publish sensor values and subscribe to control values - vnconfig->type_config.mqtt_conf->subscribe = "agent_"+std::to_string(id)+"_ctrl"; - vnconfig->type_config.mqtt_conf->publish = "agent_"+std::to_string(id)+"_sen"; + std::string name = "agent_" + std::to_string(id); + std::string custom_param_json_string = "{\"name\": \"" + name + "\", \"out\": {\"publish\": \"" + name + "_sen\"}, \"in\": {\"subscribe\": \"" + name + "_ctrl\"}}"; + //vnconfig->type_config.mqtt_conf->subscribe = "agent_"+std::to_string(id)+"_ctrl"; + //vnconfig->type_config.mqtt_conf->publish = "agent_"+std::to_string(id)+"_sen"; + + //Initialize villas interface + int ret = init_villas_interface(custom_param_json_string); + if (ret){ + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); - //Initialize villas interface (important: after init of message meta info!) - int ret = init_villas_interface(vnconfig, Ensure_msg::ensure_msg_meta); - return ret; + return 0; } @@ -105,15 +121,9 @@ void Ensure_behavior::handshake() { timer->reset(); //prepare and send handshake message - Ensure_msg handshake_msg; + Ensure_msg handshake_msg(FIPA_PERF_INFORM, id, 0.0, 0.0, 0, 0.0, 0.0, 0.0, false, 0); handshake_msg.time_sec = t_next; - *(handshake_msg.agent_id) = id; - *(handshake_msg.performative) = FIPA_PERF_INFORM; - *(handshake_msg.P) = 0.0; - *(handshake_msg.Q) = 0.0; - *(handshake_msg.n) = 0; - *(handshake_msg.v) = 0.0; - IO->log_info("\tSend message: " + handshake_msg.get_message_output()); + IO->log_info("\tSend message: " + handshake_msg.toString()); send_villas_msg(handshake_msg); /// TODO: uncomment from here to use handshake mechanism @@ -128,7 +138,7 @@ void Ensure_behavior::handshake() { //receive villas messages (only one message should be received for this topic) incoming_villas_messages.clear(); - villas_interface->receive_messages(incoming_villas_messages); + villas_interface->receive(incoming_villas_messages, 1, false); if(!incoming_villas_messages.empty()){ break; @@ -155,15 +165,17 @@ void Ensure_behavior::handshake() { MPI_Abort(MPI_COMM_WORLD, -7); } else { - Ensure_msg msg = (Ensure_msg) incoming_villas_messages.front(); - msg.set_pointers(); - IO->log_info("\tReceived handshake response: " + msg.get_message_output()); - if( *msg.performative == FIPA_PERF_INFORM && - *msg.agent_id == id && - *msg.P == 0 && - *msg.Q == 0 && - *msg.n == 0 && - *msg.v == 0) + auto msg = incoming_villas_messages.front(); + + IO->log_info("\tReceived handshake response: " + msg.toString()); + + if(msg.data.at(0).i == FIPA_PERF_INFORM && + msg.data.at(1).i == id && + msg.data.at(2).f == 0.0 && + msg.data.at(3).f == 0.0 && + msg.data.at(4).i == 0 && + msg.data.at(5).f == 0.0 + ) { IO->log_info("\tHandshake with cloud platform agent completed successfully!"); } @@ -190,12 +202,4 @@ void Ensure_behavior::handshake() { } -/*! - * \brief sending function for messages - * \param msg message to be sent - */ -void Ensure_behavior::send_villas_msg(Villas_message &msg) -{ - villas_interface->send_message(msg); -} - +#endif \ No newline at end of file diff --git a/src/behavior/ensure/ensure_knowledge.cpp b/src/behavior/ensure/ensure_knowledge.cpp index 364a26c4d26fcbaf31fcf493e2c8eab8e01fd4ff..5a4643161d928abc671c9e02e22fa160c6e21d65 100644 --- a/src/behavior/ensure/ensure_knowledge.cpp +++ b/src/behavior/ensure/ensure_knowledge.cpp @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include #include "behavior/ensure/ensure_knowledge.h" @@ -274,3 +274,4 @@ void Ensure_knowledge::log_sensor_knowledge() IO->log_info(output); return; } +#endif \ No newline at end of file diff --git a/src/behavior/ensure/ensure_message.cpp b/src/behavior/ensure/ensure_message.cpp index fefb83d9d751e38a4dbe642c4b172a9390d49f65..d92610de35e1c91d338afca4c8e40dd4faed2f73 100644 --- a/src/behavior/ensure/ensure_message.cpp +++ b/src/behavior/ensure/ensure_message.cpp @@ -14,208 +14,54 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/ensure/ensure_message.h" #include -std::vector Ensure_msg::ensure_msg_meta = std::vector(); -bool Ensure_msg::meta_initialized = false; - -Ensure_msg::Ensure_msg() : Villas_message() { - - performative = nullptr; - agent_id = nullptr; - P = nullptr; - Q = nullptr; - n = nullptr; - v = nullptr; - v2 = nullptr; - SOC = nullptr; - connected = nullptr; - t_connected = nullptr; - - init_message(0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, false, 0); - -} - -Ensure_msg::Ensure_msg(Villas_message &msg) : Villas_message(){ - data = msg.data; - length = msg.length; - -} - - -Ensure_msg::Ensure_msg(int _performative, int _agent_id) { - performative = nullptr; - agent_id = nullptr; - P = nullptr; - Q = nullptr; - n = nullptr; - v = nullptr; - v2 = nullptr; - SOC = nullptr; - connected = nullptr; - t_connected = nullptr; - - init_message(_performative, _agent_id, 0, 0.0, 0, 0.0, 0.0, 0.0, false, 0); +Ensure_msg::Ensure_msg(int64_t performative, + int64_t agent_id, + double P, + double Q, + int64_t n, + double v, + double v2, + double SOC, + bool connected, + int64_t t_connected + ) : Villas_message() { + + Data_element d1, d2, d3, d4, d5, d6, d7, d8, d9, d10; + d1.i = performative; + d2.i = agent_id; + d3.f = P; + d4.f = Q; + d5.i = n; + d6.f = v; + d7.f = v2; + d8.f = SOC; + d9.b = connected; + d10.i = t_connected; + + data.push_back(d1); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d2); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d3); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d4); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d5); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d6); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d7); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d8); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d9); + data_types.push_back(VILLASMSG_BOOLEAN); + data.push_back(d10); + data_types.push_back(VILLASMSG_INTEGER); + length = data.size(); } - -void Ensure_msg::set_pointers() { - - //set the pointer to the elements in data field - //if you change the order or data types of data elements you have to adapt the indices here - performative = &(data[0].i); - agent_id = &(data[1].i); - P = &(data[2].f); - Q = &(data[3].f); - n = &(data[4].i); - v = &(data[5].f); - v2 = &(data[6].f); - SOC = &(data[7].f); - connected = &(data[8].b); - t_connected = &(data[9].i); -} - -void Ensure_msg::init_message(int _performative, int _agent_id, double _P, double _Q, int _n, double _v, double _v2, double _SOC, bool _conn, int _t_conn) { - - //add all data and meta elements of this message type - Data_element perf_data; - perf_data.i = _performative; - add_element(perf_data, VILLAS_DATA_TYPE_INT64); - - Data_element sender_data; - sender_data.i = _agent_id; - add_element(sender_data, VILLAS_DATA_TYPE_INT64); - - Data_element P_data; - P_data.f = _P; - add_element(P_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element Q_data; - Q_data.f = _Q; - add_element(Q_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element n_data; - n_data.i = _n; - add_element(n_data, VILLAS_DATA_TYPE_INT64); - - Data_element v_data; - v_data.f = _v; - add_element(v_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element v2_data; - v2_data.f = _v2; - add_element(v2_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element soc_data; - soc_data.f = _SOC; - add_element(soc_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element conn_data; - conn_data.b = _conn; - add_element(conn_data, VILLAS_DATA_TYPE_BOOLEAN); - - Data_element t_conn_data; - t_conn_data.i = _t_conn; - add_element(t_conn_data, VILLAS_DATA_TYPE_INT64); - - //set the pointers of the message to the corresponding fields in data - set_pointers(); -} - - -void Ensure_msg::init_meta() { - // returns immediately if static meta information has already been initialized for this message type - //initialize meta info only once - if(!Ensure_msg::meta_initialized) { - Ensure_msg::meta_initialized = true; - Ensure_msg::ensure_msg_meta.clear(); - - Meta_infos perf_meta; - perf_meta.name = "performative"; - perf_meta.unit = "peformative of this message"; - perf_meta.type = VILLAS_DATA_TYPE_INT64; - Ensure_msg::ensure_msg_meta.push_back(perf_meta); - - Meta_infos sender_meta; - sender_meta.name = "agent_id"; - sender_meta.unit = "id of agent involved in this message"; - sender_meta.type = VILLAS_DATA_TYPE_INT64; - Ensure_msg::ensure_msg_meta.push_back(sender_meta); - - Meta_infos P_meta; - P_meta.name = "P"; - P_meta.unit = "W"; - P_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Ensure_msg::ensure_msg_meta.push_back(P_meta); - - Meta_infos Q_meta; - Q_meta.name = "Q"; - Q_meta.unit = "var"; - Q_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Ensure_msg::ensure_msg_meta.push_back(Q_meta); - - Meta_infos n_meta; - n_meta.name = "n"; - n_meta.unit = "tap pos"; - n_meta.type = VILLAS_DATA_TYPE_INT64; - Ensure_msg::ensure_msg_meta.push_back(n_meta); - - Meta_infos v_meta; - v_meta.name = "v"; - v_meta.unit = "V"; - v_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Ensure_msg::ensure_msg_meta.push_back(v_meta); - - Meta_infos v2_meta; - v2_meta.name = "v2"; - v2_meta.unit = "V"; - v2_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Ensure_msg::ensure_msg_meta.push_back(v2_meta); - - Meta_infos soc_meta; - soc_meta.name = "SOC"; - soc_meta.unit = "state of charge"; - soc_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Ensure_msg::ensure_msg_meta.push_back(soc_meta); - - Meta_infos conn_meta; - conn_meta.name = "connected"; - conn_meta.unit = "boolean"; - conn_meta.type = VILLAS_DATA_TYPE_BOOLEAN; - Ensure_msg::ensure_msg_meta.push_back(conn_meta); - - Meta_infos t_conn_meta; - t_conn_meta.name = "t_connected"; - t_conn_meta.unit = "s"; - t_conn_meta.type = VILLAS_DATA_TYPE_INT64; - Ensure_msg::ensure_msg_meta.push_back(t_conn_meta); - } - -} - -/*! -* \brief Writes the content of a message to a string for debugging -* \return Message content as string -* */ -std::string Ensure_msg::get_message_output() -{ - std::stringstream temp; - std::string output; - - temp << "Time: " << time_sec - << " Agent ID: " << *agent_id - << " Performative: " << *performative - << " P: " << *P - << " Q: " << *Q - << " n: " << *n - << " v: " << *v - << " v2: " << *v2 - << " SOC: " << *SOC - << " connected: " << *connected - << " t_connected: " << *t_connected; - - output = temp.str(); - return output; -} - +#endif diff --git a/src/behavior/ensure/ensure_prosumer_behavior.cpp b/src/behavior/ensure/ensure_prosumer_behavior.cpp index 5a13829e37d9d0f1ddc0e4c192b9c991dee5448f..764ec526e2af1b27e8a2a36c985acfd848332f11 100644 --- a/src/behavior/ensure/ensure_prosumer_behavior.cpp +++ b/src/behavior/ensure/ensure_prosumer_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/ensure/ensure_prosumer_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,9 +26,9 @@ * \param _prosumer_data [in] pointer to prosumer specific datastruct * */ Ensure_prosumer_behavior::Ensure_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data) - : Ensure_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Ensure_behavior(_id, _type, _rank, _subtype, step_size, _d_props), prosumer_data(_prosumer_data) { knowledge.init(_id, IO); @@ -58,15 +57,14 @@ void Ensure_prosumer_behavior::execute_agent_behavior() knowledge.log_sensor_knowledge(); } -void Ensure_prosumer_behavior::process_ensure_msg(Ensure_msg &msg) +void Ensure_prosumer_behavior::process_ensure_msg(Villas_message &msg) { knowledge.set_t_recv(t_next); if (type == TYPE_COMPENSATOR_INT) { - knowledge.set_n_ctrl(*(msg.n)); + knowledge.set_n_ctrl(msg.data.at(4).i); } else { - knowledge.set_PQ_ctrl(*(msg.P), *(msg.Q)); + knowledge.set_PQ_ctrl(msg.data.at(2).f, msg.data.at(2).f); } - return; } void Ensure_prosumer_behavior::send_measurement_message() @@ -74,60 +72,66 @@ void Ensure_prosumer_behavior::send_measurement_message() if (t_next - knowledge.get_t_sent() > 10) { double v = sqrt(prosumer_data->v_re * prosumer_data->v_re + prosumer_data->v_im * prosumer_data->v_im); - Ensure_msg new_msg; - new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.v) = v; + + + double P = 0.0; + double Q = 0.0; + double soc = 0.0; + bool connected = false; + int t_connected = 0; + switch (type){ case TYPE_BATTERY_INT: { - *(new_msg.SOC) = prosumer_data->SOC_el; + soc = prosumer_data->SOC_el; knowledge.set_SOC_meas(prosumer_data->SOC_el); break; } case TYPE_LOAD_INT: { - *(new_msg.P) = prosumer_data->P_dem; - *(new_msg.Q) = prosumer_data->Q_dem; + P = prosumer_data->P_dem; + Q = prosumer_data->Q_dem; knowledge.set_PQ_meas(prosumer_data->P_dem, prosumer_data->Q_dem); break; } case TYPE_EV_INT: { - *(new_msg.SOC) = prosumer_data->SOC_el; - *(new_msg.connected) = prosumer_data->connected; - *(new_msg.t_connected) = prosumer_data->t_connected; + soc = prosumer_data->SOC_el; + connected = prosumer_data->connected; + t_connected = (int) prosumer_data->t_connected; knowledge.set_SOC_meas(prosumer_data->SOC_el); knowledge.set_conn(prosumer_data->connected); knowledge.set_t_conn(prosumer_data->t_connected); break; } case TYPE_HP_INT: { - *(new_msg.P) = prosumer_data->P_th_dem; - *(new_msg.SOC) = prosumer_data->SOC_th; + P = prosumer_data->P_th_dem; + soc = prosumer_data->SOC_th; knowledge.set_Pth_meas(prosumer_data->P_th_dem); break; } case TYPE_CHP_INT: { - *(new_msg.P) = prosumer_data->P_th_dem; - *(new_msg.SOC) = prosumer_data->SOC_th; + P = prosumer_data->P_th_dem; + soc = prosumer_data->SOC_th; knowledge.set_Pth_meas(prosumer_data->P_th_dem); break; } case TYPE_PV_INT: { - *(new_msg.P) = prosumer_data->P_gen; + P = prosumer_data->P_gen; knowledge.set_PQ_meas(prosumer_data->P_gen, 0); break; } case TYPE_WEC_INT: { - *(new_msg.P) = prosumer_data->P_gen; + P = prosumer_data->P_gen; knowledge.set_PQ_meas(prosumer_data->P_gen, 0); break; } } - IO->log_info("\tSend message: " + new_msg.get_message_output()); + + Ensure_msg new_msg(FIPA_PERF_INFORM, id, P, Q, 0, v, 0.0, soc, connected, t_connected); + new_msg.time_sec = t_next; + + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); knowledge.set_t_sent(t_next); } - return; } /*! \brief determine the limits and optimal operation @@ -404,17 +408,9 @@ void Ensure_prosumer_behavior::publish_voltage_measurement() std::complex meas; meas.real(prosumer_data->v_re / (prosumer_data->Vnom / sqrt(3))); meas.imag(prosumer_data->v_im / (prosumer_data->Vnom / sqrt(3))); - Ensure_msg new_msg; + Ensure_msg new_msg(FIPA_PERF_INFORM, id, 0.0, 0.0, 0, std::abs(meas), 0.0, 0.0, false, 0); new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.P) = 0.0; - *(new_msg.Q) = 0.0; - *(new_msg.n) = 0; - *(new_msg.v) = std::abs(meas); - *(new_msg.SOC) = 0.0; - *(new_msg.connected) = false; - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); } } @@ -433,7 +429,6 @@ void Ensure_prosumer_behavior::apply_control_values() IO->log_info("\tApplying control values\n\t\tP_ctrl: " + std::to_string(prosumer_data->P_ctrl) + "W Q_ctrl: " + std::to_string(prosumer_data->Q_ctrl) + "var"); - return; } @@ -456,3 +451,4 @@ double Ensure_prosumer_behavior::get_q_available(double p) return q_available; } +#endif \ No newline at end of file diff --git a/src/behavior/ensure/ensure_slack_behavior.cpp b/src/behavior/ensure/ensure_slack_behavior.cpp index 1d513e840fba60b994783b5ac676f43167045b3b..2825238b32fcf5a91b48c44e2dc6f60b5782175d 100644 --- a/src/behavior/ensure/ensure_slack_behavior.cpp +++ b/src/behavior/ensure/ensure_slack_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/ensure/ensure_slack_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,9 +26,9 @@ * \param _prosumer_data [in] pointer to prosumer specific datastruct * */ Ensure_slack_behavior::Ensure_slack_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Slack_data * _slack_data) - : Ensure_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Ensure_behavior(_id, _type, _rank, _subtype, step_size, _d_props), slack_data(_slack_data) { knowledge.init(_id, IO); @@ -54,26 +53,21 @@ void Ensure_slack_behavior::execute_agent_behavior() knowledge.log_sensor_knowledge(); } -void Ensure_slack_behavior::process_ensure_msg(Ensure_msg &msg) +void Ensure_slack_behavior::process_ensure_msg(Villas_message &msg) { knowledge.set_t_recv(t_next); // no ensure msg should be received - return; } void Ensure_slack_behavior::send_measurement_message() { if (t_next - knowledge.get_t_sent() > 10) { - Ensure_msg new_msg; + Ensure_msg new_msg (FIPA_PERF_INFORM, id, slack_data->P, slack_data->Q, 0, 0.0, 0.0, 0.0, false, 0); new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.P) = slack_data->P; - *(new_msg.Q) = slack_data->Q; - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); knowledge.set_t_sent(t_next); } - return; } +#endif diff --git a/src/behavior/ensure/ensure_substation_behavior.cpp b/src/behavior/ensure/ensure_substation_behavior.cpp index 88fae161ad90e4f80eb31044b2dfa7972d55c15b..c611df5e26989392770f562d053d019694b1f675 100644 --- a/src/behavior/ensure/ensure_substation_behavior.cpp +++ b/src/behavior/ensure/ensure_substation_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/ensure/ensure_substation_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,9 +26,9 @@ * \param _substation_data [in] pointer to substation specific datastruct * */ Ensure_substation_behavior::Ensure_substation_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Substation_data * _substation_data) - : Ensure_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Ensure_behavior(_id, _type, _rank, _subtype, step_size, _d_props), substation_data(_substation_data) { knowledge.init(_id, IO); @@ -52,11 +51,10 @@ void Ensure_substation_behavior::execute_agent_behavior() apply_control_values(); } -void Ensure_substation_behavior::process_ensure_msg(Ensure_msg &msg) +void Ensure_substation_behavior::process_ensure_msg(Villas_message &msg) { knowledge.set_t_recv(t_next); - knowledge.set_n_ctrl(*(msg.n)); - return; + knowledge.set_n_ctrl(msg.data.at(4).i); } void Ensure_substation_behavior::send_measurement_message() @@ -66,19 +64,14 @@ void Ensure_substation_behavior::send_measurement_message() substation_data->v1_im * substation_data->v1_im); double v2 = sqrt(substation_data->v2_re * substation_data->v2_re + substation_data->v2_im * substation_data->v2_im); - Ensure_msg new_msg; + Ensure_msg new_msg(FIPA_PERF_INFORM, id, 0.0, 0.0, 0, v1, v2, 0.0, false, 0); new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.v) = v1; - *(new_msg.v2) = v2; knowledge.set_v_meas(v1); knowledge.set_v2_meas(v2); - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); knowledge.set_t_sent(t_next); } - return; } @@ -90,5 +83,5 @@ void Ensure_substation_behavior::apply_control_values() IO->log_info("\tApplying control values\n\t\tn_ctrl: " + std::to_string(substation_data->n_ctrl)); - return; } +#endif diff --git a/src/behavior/mqtt_highload/mqtt_highload_behavior.cpp b/src/behavior/mqtt_highload/mqtt_highload_behavior.cpp index 96a24879137535a9faaef847b53d3dfeb1aee87a..e0425fcbced692a826f6cfba8771c3896d37abf9 100644 --- a/src/behavior/mqtt_highload/mqtt_highload_behavior.cpp +++ b/src/behavior/mqtt_highload/mqtt_highload_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_highload/mqtt_highload_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief constructor * \param _id unique ID of agent @@ -26,11 +25,11 @@ * \param logging indicates if agents logs locally * */ Mqtt_highload_behavior::Mqtt_highload_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, - struct data_props _d_props, villas_node_config * _villas_config) + struct data_props _d_props) : Agent_behavior(_id, _type, _subtype, step_size, _d_props) { - vnconfig = _villas_config; + //vnconfig = _villas_config; if(_type == TYPE_DF_INT) { std::string path = "runlog/behavior/agent_DF" + std::to_string(_rank) + ".log"; @@ -41,37 +40,22 @@ Mqtt_highload_behavior::Mqtt_highload_behavior(int _id, int _type, int _rank, st IO->init_logging(); } -Mqtt_highload_behavior::~Mqtt_highload_behavior(){ - //destroy_villas_interface is called in agent method - IO->finish_io(); +/*! \brief global initializations (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Mqtt_highload_behavior::global_init(std::string config_file_path, int rank) { + /*init the global instance and start the node type*/ + return Villas_interface::start_node_type(config_file_path, rank); } - -/*! \brief Initialize the agent behavior - * \param components_ad_nodes [in] vector saving a list of connceted components for each node - * \param connected_nodes [in] vector saving a list of connected nodes for each node - * \param components_file [in] data contained in scenario components input file (integers) - * \param subtypes_file [in] subtypes contained in scenario components input file (strings) - * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) +/*! \brief global cleanup (process-wide) for behavior + * \return 0 on success, other number on error * */ -int Mqtt_highload_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file) { - //set connection parameters - set_connection_params(components_at_nodes); - - //initialize meta information for all message types used in this behavior - Mqtt_highload_msg::init_meta(); - - //Initialize villas interface (important: after init of message meta info!) - int ret = init_villas_interface(vnconfig, Mqtt_highload_msg::mqtt_highload_msg_meta); - return ret; +int Mqtt_highload_behavior::global_cleanup() { + return Villas_interface::stop_node_type(); } - /*! \brief process all messages that have been received since the last time step and call protocol * specific process function * */ @@ -79,26 +63,15 @@ void Mqtt_highload_behavior::process_incoming_messages() { std::list incoming_villas_messages; - villas_interface->receive_messages(incoming_villas_messages); + villas_interface->receive(incoming_villas_messages, 1000, false); while (!incoming_villas_messages.empty()) { - Mqtt_highload_msg mqtt_msg = (Mqtt_highload_msg) incoming_villas_messages.front(); - //set pointers of data to members - mqtt_msg.set_pointers(); - IO->log_info("\tReceived message: " + mqtt_msg.get_message_output()); + auto mqtt_msg = incoming_villas_messages.front(); + + IO->log_info("\tReceived message: " + mqtt_msg.toString()); this->process_mqtt_highload_msg(mqtt_msg); incoming_villas_messages.pop_front(); } } - - -/*! - * \brief sending function for mqtt messages - * \param msg message to be sent - */ -void Mqtt_highload_behavior::send_villas_msg(Villas_message &msg) -{ - villas_interface->send_message(msg); -} - +#endif diff --git a/src/behavior/mqtt_highload/mqtt_highload_message.cpp b/src/behavior/mqtt_highload/mqtt_highload_message.cpp index 19e63caffcff0f068691413603f28e3bb1fbd997..249edd43b6b849d2d1ba9a1fea734dd08642ea8a 100644 --- a/src/behavior/mqtt_highload/mqtt_highload_message.cpp +++ b/src/behavior/mqtt_highload/mqtt_highload_message.cpp @@ -14,200 +14,50 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_highload/mqtt_highload_message.h" #include -std::vector Mqtt_highload_msg::mqtt_highload_msg_meta = std::vector(); -bool Mqtt_highload_msg::meta_initialized = false; - -Mqtt_highload_msg::Mqtt_highload_msg() : Villas_message() { - - performative = nullptr; - sender = nullptr; - receiver = nullptr; - measurement_type_1 = nullptr; - measurement_value_1 = nullptr; - measurement_type_2 = nullptr; - measurement_value_2 = nullptr; - measurement_type_3 = nullptr; - measurement_value_3 = nullptr; - - init_message(0,0,0,0,0.0,0,0.0,0,0.0); -} - -Mqtt_highload_msg::Mqtt_highload_msg(Villas_message &msg) : Villas_message(){ - data = msg.data; - length = msg.length; - -} - - -Mqtt_highload_msg::Mqtt_highload_msg(int _performative, int _sender, int _receiver) { - performative = nullptr; - sender = nullptr; - receiver = nullptr; - measurement_type_1 = nullptr; - measurement_value_1 = nullptr; - measurement_type_2 = nullptr; - measurement_value_2 = nullptr; - measurement_type_3 = nullptr; - measurement_value_3 = nullptr; - - init_message(_performative,_sender,_receiver,0,0.0,0,0.0,0,0.0); -} - -void Mqtt_highload_msg::set_pointers() { - - //set the pointer to the elements in data field - //if you change the order or data types of data elements you have to adapt the indices here - performative = &(data[0].i); - sender = &(data[1].i); - receiver = &(data[2].i); - measurement_type_1 = &(data[3].i); - measurement_value_1 = &(data[4].f); - measurement_type_2 = &(data[5].i); - measurement_value_2 = &(data[6].f); - measurement_type_3 = &(data[7].i); - measurement_value_3 = &(data[8].f); +Mqtt_highload_msg::Mqtt_highload_msg(int64_t performative, + int64_t sender, + int64_t receiver, + int64_t type1, + double value1, + int64_t type2, + double value2, + int64_t type3, + double value3 + ) : Villas_message() { + + Data_element d1, d2, d3, d4, d5, d6, d7, d8, d9; + d1.i = performative; + d2.i = sender; + d3.i = receiver; + d4.i = type1; + d5.f = value1; + d6.i = type2; + d7.f = value2; + d8.i = type3; + d9.f = value3; + + data.push_back(d1); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d2); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d3); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d4); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d5); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d6); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d7); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d8); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d9); + data_types.push_back(VILLASMSG_FLOAT); + length = data.size(); } - -void Mqtt_highload_msg::init_message(int _performative, int _sender, int _receiver, - int _measurement_type_1, double _measurement_value_1, - int _measurement_type_2, double _measurement_value_2, - int _measurement_type_3, double _measurement_value_3) { - - //add all data and meta elements of this message type - Data_element perf_data; - perf_data.i = _performative; - add_element(perf_data, VILLAS_DATA_TYPE_INT64); - - Data_element sender_data; - sender_data.i = _sender; - add_element(sender_data, VILLAS_DATA_TYPE_INT64); - - Data_element receiver_data; - receiver_data.i = _receiver; - add_element(receiver_data, VILLAS_DATA_TYPE_INT64); - - - Data_element measurement_type_data_1; - measurement_type_data_1.i = _measurement_type_1; - add_element(measurement_type_data_1, VILLAS_DATA_TYPE_INT64); - - Data_element measurement_value_data_1; - measurement_value_data_1.f = _measurement_value_1; - add_element(measurement_value_data_1, VILLAS_DATA_TYPE_DOUBLE); - - - Data_element measurement_type_data_2; - measurement_type_data_2.i = _measurement_type_2; - add_element(measurement_type_data_2, VILLAS_DATA_TYPE_INT64); - - Data_element measurement_value_data_2; - measurement_value_data_2.f = _measurement_value_2; - add_element(measurement_value_data_2, VILLAS_DATA_TYPE_DOUBLE); - - - Data_element measurement_type_data_3; - measurement_type_data_3.i = _measurement_type_3; - add_element(measurement_type_data_3, VILLAS_DATA_TYPE_INT64); - - Data_element measurement_value_data_3; - measurement_value_data_3.f = _measurement_value_3; - add_element(measurement_value_data_3, VILLAS_DATA_TYPE_DOUBLE); - - //set the pointers of the message to the corresponding fields in data - set_pointers(); -} - - -void Mqtt_highload_msg::init_meta() { - // returns immediately if static meta information has already been initialized for this message type - // initialize meta info only once - if(!Mqtt_highload_msg::meta_initialized) { - Mqtt_highload_msg::meta_initialized = true; - Mqtt_highload_msg::mqtt_highload_msg_meta.clear(); - - Meta_infos perf_meta; - perf_meta.name = "performative"; - perf_meta.unit = "peformative of this message"; - perf_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(perf_meta); - - Meta_infos sender_meta; - sender_meta.name = "sender"; - sender_meta.unit = "sender of this message"; - sender_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(sender_meta); - - Meta_infos receiver_meta; - receiver_meta.name = "receiver"; - receiver_meta.unit = "receiver of this message"; - receiver_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(receiver_meta); - - - Meta_infos measurement_type_meta_1; - measurement_type_meta_1.name = "measurement_type_1"; - measurement_type_meta_1.unit = "measurement_type_1 of this message"; - measurement_type_meta_1.type = VILLAS_DATA_TYPE_INT64; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(measurement_type_meta_1); - - Meta_infos measurement_value_meta_1; - measurement_value_meta_1.name = "measurement_value_1"; - measurement_value_meta_1.unit = "measurement_value_1 of this message"; - measurement_value_meta_1.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(measurement_value_meta_1); - - Meta_infos measurement_type_meta_2; - measurement_type_meta_2.name = "measurement_type_2"; - measurement_type_meta_2.unit = "measurement_type_2 of this message"; - measurement_type_meta_2.type = VILLAS_DATA_TYPE_INT64; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(measurement_type_meta_2); - - Meta_infos measurement_value_meta_2; - measurement_value_meta_2.name = "measurement_value_2"; - measurement_value_meta_2.unit = "measurement_value_2 of this message"; - measurement_value_meta_2.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(measurement_value_meta_2); - - Meta_infos measurement_type_meta_3; - measurement_type_meta_3.name = "measurement_type_3"; - measurement_type_meta_3.unit = "measurement_type_3 of this message"; - measurement_type_meta_3.type = VILLAS_DATA_TYPE_INT64; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(measurement_type_meta_3); - - Meta_infos measurement_value_meta_3; - measurement_value_meta_3.name = "measurement_value_3"; - measurement_value_meta_3.unit = "measurement_value_3 of this message"; - measurement_value_meta_3.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_highload_msg::mqtt_highload_msg_meta.push_back(measurement_value_meta_3); - - } - -} - -/*! -* \brief Writes the content of a message to a string for debugging -* \return Message content as string -* */ -std::string Mqtt_highload_msg::get_message_output() -{ - std::stringstream temp; - std::string output; - - temp << "Time: " << time_sec - << " Sender: " << *sender - << " Receiver: " << *receiver - << " Performative: " << *performative - << " Type_1: " << *measurement_type_1 - << " Value_1: " << *measurement_value_1 - << " Type_2: " << *measurement_type_2 - << " Value_2: " << *measurement_value_2 - << " Type_3: " << *measurement_type_3 - << " Value_3: " << *measurement_value_3; - - output = temp.str(); - return output; -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.cpp b/src/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.cpp index ee3c2eb0680c881ee4daf7a2f59ac3763bbd77d0..56102eb303507c01ce16518da30c84a3209f3617 100644 --- a/src/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.cpp +++ b/src/behavior/mqtt_highload/mqtt_highload_prosumer_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_highload/mqtt_highload_prosumer_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,26 +26,48 @@ * \param _prosumer_data [in] pointer to prosumer specific datastruct * */ Mqtt_highload_prosumer_behavior::Mqtt_highload_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data) - : Mqtt_highload_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Mqtt_highload_behavior(_id, _type, _rank, _subtype, step_size, _d_props), prosumer_data(_prosumer_data) {} - -/*! \brief set connection parameters for this behavior - * \param components_at_nodes provides overview on components connected to nodes +/*! \brief Initialize the agent behavior + * \param components_ad_nodes [in] vector saving a list of connceted components for each node + * \param connected_nodes [in] vector saving a list of connected nodes for each node + * \param components_file [in] data contained in scenario components input file (integers) + * \param subtypes_file [in] subtypes contained in scenario components input file (strings) + * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) * */ -void Mqtt_highload_prosumer_behavior::set_connection_params(std::vector>> * components_at_nodes) { +int Mqtt_highload_prosumer_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) { std::list> node_components = components_at_nodes->at (prosumer_data->node_id-1); - //prosumers publish voltage measuerments and subscribe to nothing - vnconfig->type_config.mqtt_conf->subscribe = ""; - vnconfig->type_config.mqtt_conf->publish = "/1234/node_" + std::to_string(type) + "/attrs"; + //Initialize villas interface + std::string custom_param_json_string = "{\"name\": \"agent_" + std::to_string(id) + "\", \"out\": {\"publish\": \"/1234/node_" + std::to_string(type) + "/attrs\"}, \"in\": {\"subscribe\":\"\"}}"; + //prosumers publish voltage measurements and subscribe to nothing + //vnconfig->type_config.mqtt_conf->subscribe = ""; + //vnconfig->type_config.mqtt_conf->publish = "/1234/node_" + std::to_string(type) + "/attrs"; + int ret = init_villas_interface(custom_param_json_string); + if(ret){ + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); + + return 0; } + /*! \brief adjusts control values according to simple rules not requiring communication * */ void Mqtt_highload_prosumer_behavior::execute_agent_behavior() @@ -62,7 +83,7 @@ void Mqtt_highload_prosumer_behavior::execute_agent_behavior() apply_control_values(); } -void Mqtt_highload_prosumer_behavior::process_mqtt_highload_msg(Mqtt_highload_msg &msg) +void Mqtt_highload_prosumer_behavior::process_mqtt_highload_msg(Villas_message &msg) { } @@ -73,22 +94,9 @@ void Mqtt_highload_prosumer_behavior::publish_measurement_data() std::complex meas; meas.real(prosumer_data->v_re / (prosumer_data->Vnom / sqrt(3))); meas.imag(prosumer_data->v_im / (prosumer_data->Vnom / sqrt(3))); - Mqtt_highload_msg new_msg; + Mqtt_highload_msg new_msg(FIPA_PERF_INFORM, id, -1, 0, std::abs(meas), 1, prosumer_data->P, 2, prosumer_data->Q); new_msg.time_sec = t_next; - *(new_msg.sender) = id; - *(new_msg.receiver) = -1; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.measurement_type_1) = 0; - *(new_msg.measurement_value_1) = std::abs(meas); - //IO->log_info("\tSend message: " + new_msg.get_message_output()); - *(new_msg.measurement_type_2) = 1; - *(new_msg.measurement_value_2) = prosumer_data->P; - *(new_msg.measurement_type_3) = 2; - *(new_msg.measurement_value_3) = prosumer_data->Q; send_villas_msg(new_msg); - /**(new_msg.measurement_type) = 3; - *(new_msg.measurement_value) = prosumer_data->C_el; - send_villas_msg(new_msg);*/ } } @@ -392,3 +400,4 @@ double Mqtt_highload_prosumer_behavior::get_q_available(double p) return q_available; } +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_highload/mqtt_highload_substation_behavior.cpp b/src/behavior/mqtt_highload/mqtt_highload_substation_behavior.cpp index f96181be0561939124b984165c36bceecfd75526..8f6340004e72f419ba6238a08fd1103ab5c83f80 100644 --- a/src/behavior/mqtt_highload/mqtt_highload_substation_behavior.cpp +++ b/src/behavior/mqtt_highload/mqtt_highload_substation_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_highload/mqtt_highload_substation_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,22 +26,44 @@ * \param _substation_data [in] pointer to substation specific datastruct * */ Mqtt_highload_substation_behavior::Mqtt_highload_substation_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Substation_data * _substation_data) - : Mqtt_highload_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Mqtt_highload_behavior(_id, _type, _rank, _subtype, step_size, _d_props), substation_data(_substation_data) { voltage_measurements.clear(); } -/*! \brief set connection parameters for this behavior - * \param components_at_nodes provides overview on components connected to nodes +/*! \brief Initialize the agent behavior + * \param components_ad_nodes [in] vector saving a list of connceted components for each node + * \param connected_nodes [in] vector saving a list of connected nodes for each node + * \param components_file [in] data contained in scenario components input file (integers) + * \param subtypes_file [in] subtypes contained in scenario components input file (strings) + * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) * */ -void Mqtt_highload_substation_behavior::set_connection_params( - std::vector>> *components_at_nodes) { +int Mqtt_highload_substation_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) { + + //Initialize villas interface + std::string custom_param_json_string = "{\"name\": \"agent_" + std::to_string(id) + "\", \"out\": {\"publish\": \"/1234/node_" + std::to_string(type) + "/attrs\"}}"; //substations subscribe to voltage measurements and publish to a channel by id - //vnconfig->type_hjkconfig.mqtt_conf->subscribe = "voltage_measurements_trafo"+std::to_string(id); - vnconfig->type_config.mqtt_conf->publish = "/1234/node_" + std::to_string(type) + "/attrs"; + ////vnconfig->type_config.mqtt_conf->subscribe = "voltage_measurements_trafo"+std::to_string(id); + //vnconfig->type_config.mqtt_conf->publish = "/1234/node_" + std::to_string(type) + "/attrs"; + int ret = init_villas_interface(custom_param_json_string); + if(ret){ + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); + + return 0; } /*! \brief Substation highload behavior execution @@ -54,10 +75,10 @@ void Mqtt_highload_substation_behavior::execute_agent_behavior() apply_control_values(); } -void Mqtt_highload_substation_behavior::process_mqtt_highload_msg(Mqtt_highload_msg &msg) +void Mqtt_highload_substation_behavior::process_mqtt_highload_msg(Villas_message &msg) { - int agent_id = *msg.sender; - double voltage = *msg.measurement_value_1; + int agent_id = msg.data.at(1).i; + double voltage = msg.data.at(4).f; bool update_measurment = false; for (auto &i : voltage_measurements) { @@ -87,23 +108,8 @@ void Mqtt_highload_substation_behavior::publish_measurement_data() meas_i1.imag(substation_data->i1_im / (substation_data->Vnom1 / sqrt(3))); meas_i2.real(substation_data->i2_re / (substation_data->Vnom2 / sqrt(3))); meas_i2.imag(substation_data->i2_im / (substation_data->Vnom2 / sqrt(3))); - Mqtt_highload_msg new_msg; + Mqtt_highload_msg new_msg(FIPA_PERF_INFORM, id, -1, 0, std::abs(meas_v1), 1, std::abs(meas_v2), 3, std::abs(meas_i1)); new_msg.time_sec = t_next; - *(new_msg.sender) = id; - *(new_msg.receiver) = -1; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.measurement_type_1) = 0; - *(new_msg.measurement_value_1) = std::abs(meas_v1); - *(new_msg.measurement_type_2) = 1; - *(new_msg.measurement_value_2) = std::abs(meas_v2); - *(new_msg.measurement_type_3) = 2; - *(new_msg.measurement_value_3) = std::abs(meas_i1); - /* - *(new_msg.measurement_type) = 3; - *(new_msg.measurement_value) = std::abs(meas_i2); - send_villas_msg(new_msg); - *(new_msg.measurement_type) = 4; - *(new_msg.measurement_value) = substation_data->P_loss;*/ send_villas_msg(new_msg); } } @@ -159,3 +165,4 @@ void Mqtt_highload_substation_behavior::apply_control_values() IO->log_info("\tApplying control values\n\t\tn_ctrl: " + std::to_string(substation_data->n_ctrl)); } +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_pingpong/mqtt_pingpong_behavior.cpp b/src/behavior/mqtt_pingpong/mqtt_pingpong_behavior.cpp index a2935954af0a06149ec87a03db909c7b02ade074..b9f5f864fa891b388ebf6824361ffe35a85ca540 100644 --- a/src/behavior/mqtt_pingpong/mqtt_pingpong_behavior.cpp +++ b/src/behavior/mqtt_pingpong/mqtt_pingpong_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_pingpong/mqtt_pingpong_behavior.h" -#include "villas_interface/villas_interface.h" #include "model/time_measurement.h" /*! \brief constructor @@ -27,11 +26,11 @@ * \param logging indicates if agents logs locally * */ Mqtt_pingpong_behavior::Mqtt_pingpong_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, - struct data_props _d_props, villas_node_config * _villas_config) + struct data_props _d_props) : Agent_behavior(_id, _type, _subtype, step_size, _d_props) { - vnconfig = _villas_config; + //vnconfig = _villas_config; if(_type == TYPE_DF_INT) { std::string path = "runlog/behavior/agent_DF" + std::to_string(_rank) + ".log"; @@ -44,9 +43,19 @@ Mqtt_pingpong_behavior::Mqtt_pingpong_behavior(int _id, int _type, int _rank, st } -Mqtt_pingpong_behavior::~Mqtt_pingpong_behavior(){ - //destroy_villas_interface is called in agent method - IO->finish_io(); +/*! \brief global initializations (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Mqtt_pingpong_behavior::global_init(std::string config_file_path, int rank) { + /*init the global instance and start the node type*/ + return Villas_interface::start_node_type(config_file_path, rank); +} + +/*! \brief global cleanup (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Mqtt_pingpong_behavior::global_cleanup() { + return Villas_interface::stop_node_type(); } /*! \brief process all messages that have been received since the last time step and call protocol @@ -55,14 +64,12 @@ Mqtt_pingpong_behavior::~Mqtt_pingpong_behavior(){ void Mqtt_pingpong_behavior::process_incoming_messages() { std::list incoming_villas_messages; - - villas_interface->receive_messages(incoming_villas_messages); + villas_interface->receive(incoming_villas_messages, 1, false); while (!incoming_villas_messages.empty()) { - Mqtt_pingpong_msg msg = (Mqtt_pingpong_msg) incoming_villas_messages.front(); - //set pointers of data to members - msg.set_pointers(); - IO->log_info("\tReceived message: " + msg.get_message_output()); + auto msg = incoming_villas_messages.front(); + + IO->log_info("\tReceived message: " + msg.toString()); this->process_mqtt_pingpong_msg(msg); incoming_villas_messages.pop_front(); @@ -83,19 +90,29 @@ int Mqtt_pingpong_behavior::initialize_agent_behavior(std::vector *subtypes_file, boost::multi_array *el_grid_file) { - - //initialize meta information for all message types used in this behavior - Mqtt_pingpong_msg::init_meta(); - //prosumers publish sensor values and subscribe to control values - vnconfig->type_config.mqtt_conf->subscribe = "agent_"+std::to_string(id)+"_ctrl"; - vnconfig->type_config.mqtt_conf->publish = "agent_"+std::to_string(id)+"_sen"; - vnconfig->type_config.mqtt_conf->retain = 0; - vnconfig->type_config.mqtt_conf->keepalive = 1000; //set to high value to avoid keepalive messages + // vnconfig->type_config.mqtt_conf->subscribe = "agent_"+std::to_string(id)+"_ctrl"; + //vnconfig->type_config.mqtt_conf->publish = "agent_"+std::to_string(id)+"_sen"; + //vnconfig->type_config.mqtt_conf->retain = 0; + //vnconfig->type_config.mqtt_conf->keepalive = 1000; + + std::string name = "agent_" + std::to_string(id); + //set keepalive to high value to avoid keepalive messages + std::string custom_param_json_string = "{\"name\": \"" + name + "\", \"out\":{\"publish\": \"" + name + "_sen\"}, \"in\":{\"subscribe\": \"" + name + "_sen\"}, \"retain\": false, \"keepalive\": 1000 }"; + + //Initialize villas interface + int ret = init_villas_interface(custom_param_json_string); + if(ret){ + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); - //Initialize villas interface (important: after init of message meta info!) - int ret = init_villas_interface(vnconfig, Mqtt_pingpong_msg::mqtt_pingpong_msg_meta); - return ret; + return 0; } @@ -107,15 +124,10 @@ void Mqtt_pingpong_behavior::handshake() { timer->reset(); //prepare and send handshake message - Mqtt_pingpong_msg handshake_msg; + IO->log_info("preparing handshake message"); + Mqtt_pingpong_msg handshake_msg(FIPA_PERF_INFORM, id, 0.0, 0.0, 0, 0.0); handshake_msg.time_sec = t_next; - *(handshake_msg.agent_id) = id; - *(handshake_msg.performative) = FIPA_PERF_INFORM; - *(handshake_msg.P_ctrl) = 0.0; - *(handshake_msg.Q_ctrl) = 0.0; - *(handshake_msg.n_ctrl) = 0; - *(handshake_msg.v_meas) = 0.0; - IO->log_info("\tSend handshake ping message: " + handshake_msg.get_message_output()); + IO->log_info("\tSend handshake ping message: " + handshake_msg.toString()); send_villas_msg(handshake_msg); /// TODO: uncomment from here to use handshake mechanism @@ -130,7 +142,7 @@ void Mqtt_pingpong_behavior::handshake() { //receive villas messages (only one message should be received for this topic) incoming_villas_messages.clear(); - villas_interface->receive_messages(incoming_villas_messages); + villas_interface->receive(incoming_villas_messages, 1, false); if(!incoming_villas_messages.empty()){ break; @@ -157,15 +169,14 @@ void Mqtt_pingpong_behavior::handshake() { MPI_Abort(MPI_COMM_WORLD, -7); } else { - Mqtt_pingpong_msg msg = (Mqtt_pingpong_msg) incoming_villas_messages.front(); - msg.set_pointers(); - IO->log_info("\tReceived handshake response: " + msg.get_message_output()); - if( *msg.performative == FIPA_PERF_INFORM && - *msg.agent_id == id && - *msg.P_ctrl == 0 && - *msg.Q_ctrl == 0 && - *msg.n_ctrl == 0 && - *msg.v_meas == 0) + auto msg = incoming_villas_messages.front(); + IO->log_info("\tReceived handshake response: " + msg.toString()); + if( msg.data.at(0).i == FIPA_PERF_INFORM && + msg.data.at(1).i == id && + msg.data.at(2).f == 0.0 && + msg.data.at(3).f == 0.0 && + msg.data.at(4).i == 0 && + msg.data.at(5).f == 0.0) { IO->log_info("\tHandshake with cloud platform agent completed successfully!"); } @@ -175,29 +186,15 @@ void Mqtt_pingpong_behavior::handshake() { } } - // TODO uncomment until the end of the method to disable self ping pong - /* + // TODO comment until the end of the method to disable self ping pong + //prepare and send ping message - Mqtt_pingpong_msg ping_msg; + Mqtt_pingpong_msg ping_msg(FIPA_PERF_INFORM, id, 111.1, 222.2, 0, 999.9); ping_msg.time_sec = t_next; - *(ping_msg.agent_id) = id; - *(ping_msg.performative) = FIPA_PERF_INFORM; - *(ping_msg.P_ctrl) = 111.1; - *(ping_msg.Q_ctrl) = 222.2; - *(ping_msg.n_ctrl) = 0; - *(ping_msg.v_meas) = 999.9; - IO->log_info("\tSend message: " + ping_msg.get_message_output()); + IO->log_info("\tSend message: " + ping_msg.toString()); send_villas_msg(ping_msg); - */ -} -/*! - * \brief sending function for messages - * \param msg message to be sent - */ -void Mqtt_pingpong_behavior::send_villas_msg(Villas_message &msg) -{ - villas_interface->send_message(msg); } +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_pingpong/mqtt_pingpong_message.cpp b/src/behavior/mqtt_pingpong/mqtt_pingpong_message.cpp index 7c76b217e7a98bc02f8f67f6ba9631d1e7ea4f07..facca0849d55fa86a310130723f9167c48ff0582 100644 --- a/src/behavior/mqtt_pingpong/mqtt_pingpong_message.cpp +++ b/src/behavior/mqtt_pingpong/mqtt_pingpong_message.cpp @@ -14,153 +14,38 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_pingpong/mqtt_pingpong_message.h" #include -std::vector Mqtt_pingpong_msg::mqtt_pingpong_msg_meta = std::vector(); -bool Mqtt_pingpong_msg::meta_initialized = false; - -Mqtt_pingpong_msg::Mqtt_pingpong_msg() : Villas_message() { - - performative = nullptr; - agent_id = nullptr; - P_ctrl = nullptr; - Q_ctrl = nullptr; - n_ctrl = nullptr; - v_meas = nullptr; - - init_message(0,0,0,0.0, 0,0.0); - -} - -Mqtt_pingpong_msg::Mqtt_pingpong_msg(Villas_message &msg) : Villas_message(){ - data = msg.data; - length = msg.length; - -} - - -Mqtt_pingpong_msg::Mqtt_pingpong_msg(int _performative, int _agent_id) { - performative = nullptr; - agent_id = nullptr; - P_ctrl = nullptr; - Q_ctrl = nullptr; - n_ctrl = nullptr; - v_meas = nullptr; - - init_message(_performative,_agent_id,0,0.0, 0, 0.0); -} - -void Mqtt_pingpong_msg::set_pointers() { - - //set the pointer to the elements in data field - //if you change the order or data types of data elements you have to adapt the indices here - performative = &(data[0].i); - agent_id = &(data[1].i); - P_ctrl = &(data[2].f); - Q_ctrl = &(data[3].f); - n_ctrl = &(data[4].i); - v_meas = &(data[5].f); -} - -void Mqtt_pingpong_msg::init_message(int _performative, int _agent_id, double _P_ctrl, double _Q_ctrl, int _n_ctrl, double _v_meas) { - - //add all data and meta elements of this message type - Data_element perf_data; - perf_data.i = _performative; - add_element(perf_data, VILLAS_DATA_TYPE_INT64); - - Data_element sender_data; - sender_data.i = _agent_id; - add_element(sender_data, VILLAS_DATA_TYPE_INT64); - - Data_element P_ctrl_data; - P_ctrl_data.f = _P_ctrl; - add_element(P_ctrl_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element Q_ctrl_data; - Q_ctrl_data.f = _Q_ctrl; - add_element(Q_ctrl_data, VILLAS_DATA_TYPE_DOUBLE); - - Data_element n_ctrl_data; - n_ctrl_data.i = _n_ctrl; - add_element(n_ctrl_data, VILLAS_DATA_TYPE_INT64); - - Data_element v_meas_data; - v_meas_data.f = _v_meas; - add_element(v_meas_data, VILLAS_DATA_TYPE_DOUBLE); - - //set the pointers of the message to the corresponding fields in data - set_pointers(); -} - - -void Mqtt_pingpong_msg::init_meta() { - // returns immediately if static meta information has already been initialized for this message type - //initialize meta info only once - if(!Mqtt_pingpong_msg::meta_initialized) { - Mqtt_pingpong_msg::meta_initialized = true; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.clear(); - - Meta_infos perf_meta; - perf_meta.name = "performative"; - perf_meta.unit = "peformative of this message"; - perf_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.push_back(perf_meta); - - Meta_infos sender_meta; - sender_meta.name = "agent_id"; - sender_meta.unit = "id of agent involved in this message"; - sender_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.push_back(sender_meta); - - Meta_infos P_ctrl_meta; - P_ctrl_meta.name = "P_ctrl"; - P_ctrl_meta.unit = "W"; - P_ctrl_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.push_back(P_ctrl_meta); - - Meta_infos Q_ctrl_meta; - Q_ctrl_meta.name = "Q_ctrl"; - Q_ctrl_meta.unit = "var"; - Q_ctrl_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.push_back(Q_ctrl_meta); - - Meta_infos n_ctrl_meta; - n_ctrl_meta.name = "n_ctrl"; - n_ctrl_meta.unit = "tap pos"; - n_ctrl_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.push_back(n_ctrl_meta); - - Meta_infos v_meas_meta; - v_meas_meta.name = "v_meas"; - v_meas_meta.unit = "V"; - v_meas_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_pingpong_msg::mqtt_pingpong_msg_meta.push_back(v_meas_meta); - - } - +Mqtt_pingpong_msg::Mqtt_pingpong_msg(int64_t performative, + int64_t agent_id, + double P_ctrl, + double Q_ctrl, + int64_t n_ctrl, + double v_meas + ) : Villas_message() { + + Data_element d1, d2, d3, d4, d5, d6; + d1.i = performative; + d2.i = agent_id; + d3.f = P_ctrl; + d4.f = Q_ctrl; + d5.i = n_ctrl; + d6.f = v_meas; + + data.push_back(d1); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d2); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d3); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d4); + data_types.push_back(VILLASMSG_FLOAT); + data.push_back(d5); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d6); + data_types.push_back(VILLASMSG_FLOAT); + length = data.size(); } - -/*! -* \brief Writes the content of a message to a string for debugging -* \return Message content as string -* */ -std::string Mqtt_pingpong_msg::get_message_output() -{ - std::stringstream temp; - std::string output; - - temp << "Time: " << time_sec - << " Agent ID: " << *agent_id - << " Performative: " << *performative - << " P_ctrl: " << *P_ctrl - << " Q_ctrl: " << *Q_ctrl - << " n_ctrl: " << *n_ctrl - << " v_meas: " << *v_meas; - - output = temp.str(); - return output; -} - +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.cpp b/src/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.cpp index 5b692837dc7ba8ea9082b292e4d0c773a0c01d6a..938d81a78f97166332ead7739f770cd7016b2583 100644 --- a/src/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.cpp +++ b/src/behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_pingpong/mqtt_pingpong_prosumer_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,9 +26,9 @@ * \param _prosumer_data [in] pointer to prosumer specific datastruct * */ Mqtt_pingpong_prosumer_behavior::Mqtt_pingpong_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data) - : Mqtt_pingpong_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Mqtt_pingpong_behavior(_id, _type, _rank, _subtype, step_size, _d_props), prosumer_data(_prosumer_data) {} @@ -54,23 +53,17 @@ void Mqtt_pingpong_prosumer_behavior::execute_agent_behavior() apply_control_values(); } -void Mqtt_pingpong_prosumer_behavior::process_mqtt_pingpong_msg(Mqtt_pingpong_msg &msg) +void Mqtt_pingpong_prosumer_behavior::process_mqtt_pingpong_msg(Villas_message &msg) { // ensure test behavior receives a ping from the cloud platform and replies with a pong std::complex meas; meas.real(prosumer_data->v_re / (prosumer_data->Vnom / sqrt(3))); meas.imag(prosumer_data->v_im / (prosumer_data->Vnom / sqrt(3))); - int counter = (int) (*msg.n_ctrl); + int counter = (int) (msg.data.at(4).i); counter++; - Mqtt_pingpong_msg new_msg; + Mqtt_pingpong_msg new_msg(msg.data.at(0).i, id, msg.data.at(2).f, msg.data.at(3).f, counter, std::abs(meas)); new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = *msg.performative; - *(new_msg.P_ctrl) = *msg.P_ctrl; - *(new_msg.Q_ctrl) = *msg.Q_ctrl; - *(new_msg.n_ctrl) = counter; - *(new_msg.v_meas) = std::abs(meas); - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); } @@ -349,15 +342,9 @@ void Mqtt_pingpong_prosumer_behavior::publish_voltage_measurement() std::complex meas; meas.real(prosumer_data->v_re / (prosumer_data->Vnom / sqrt(3))); meas.imag(prosumer_data->v_im / (prosumer_data->Vnom / sqrt(3))); - Mqtt_pingpong_msg new_msg; + Mqtt_pingpong_msg new_msg(FIPA_PERF_INFORM, id, 0.0, 0.0, 0, std::abs(meas)); new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.P_ctrl) = 0.0; - *(new_msg.Q_ctrl) = 0.0; - *(new_msg.n_ctrl) = 0; - *(new_msg.v_meas) = std::abs(meas); - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); } } @@ -397,3 +384,4 @@ double Mqtt_pingpong_prosumer_behavior::get_q_available(double p) return q_available; } +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.cpp b/src/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.cpp index 721653189d2b3a2215a637054b45c03ff890578c..499b752b4b64f4fb5bd7cc5d6e0ab07da0d77af5 100644 --- a/src/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.cpp +++ b/src/behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_pingpong/mqtt_pingpong_substation_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,9 +26,9 @@ * \param _substation_data [in] pointer to substation specific datastruct * */ Mqtt_pingpong_substation_behavior::Mqtt_pingpong_substation_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Substation_data * _substation_data) - : Mqtt_pingpong_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Mqtt_pingpong_behavior(_id, _type, _rank, _subtype, step_size, _d_props), substation_data(_substation_data) { voltage_measurements.clear(); @@ -50,22 +49,18 @@ void Mqtt_pingpong_substation_behavior::execute_agent_behavior() apply_control_values(); } -void Mqtt_pingpong_substation_behavior::process_mqtt_pingpong_msg(Mqtt_pingpong_msg &msg) +void Mqtt_pingpong_substation_behavior::process_mqtt_pingpong_msg(Villas_message &msg) { // ensure test behavior receives a ping from the cloud platform and replies with a pong double v = sqrt(substation_data->v2_re * substation_data->v2_re + substation_data->v2_im * substation_data->v2_im) / (substation_data->Vnom2 / sqrt(3)); - Mqtt_pingpong_msg new_msg; - int counter = (int) *msg.n_ctrl; + + int counter = (int) msg.data.at(4).i; counter ++; + + Mqtt_pingpong_msg new_msg(msg.data.at(0).i, id, msg.data.at(2).f, msg.data.at(3).f, counter, v); new_msg.time_sec = t_next; - *(new_msg.agent_id) = id; - *(new_msg.performative) = *msg.performative; - *(new_msg.P_ctrl) = *msg.P_ctrl; - *(new_msg.Q_ctrl) = *msg.Q_ctrl; - *(new_msg.n_ctrl) = counter; - *(new_msg.v_meas) = v; - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); } @@ -111,3 +106,4 @@ void Mqtt_pingpong_substation_behavior::apply_control_values() IO->log_info("\tApplying control values\n\t\tn_ctrl: " + std::to_string(substation_data->n_ctrl)); } +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_reference/mqtt_message.cpp b/src/behavior/mqtt_reference/mqtt_message.cpp index bd198f6f183a75f3adc6645840e288efdc57cedc..4103e4e4d68fe157f762f056d3ff0ca74f980eaa 100644 --- a/src/behavior/mqtt_reference/mqtt_message.cpp +++ b/src/behavior/mqtt_reference/mqtt_message.cpp @@ -14,138 +14,33 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_reference/mqtt_message.h" #include -std::vector Mqtt_ref_msg::mqtt_ref_msg_meta = std::vector(); -bool Mqtt_ref_msg::meta_initialized = false; - -Mqtt_ref_msg::Mqtt_ref_msg() : Villas_message() { - - performative = nullptr; - sender = nullptr; - receiver = nullptr; - measurement_type = nullptr; - measurement_value = nullptr; - - init_message(0,0,0,0,0.0); - -} - -Mqtt_ref_msg::Mqtt_ref_msg(Villas_message &msg) : Villas_message(){ - data = msg.data; - length = msg.length; - -} - - -Mqtt_ref_msg::Mqtt_ref_msg(int _performative, int _sender, int _receiver) { - performative = nullptr; - sender = nullptr; - receiver = nullptr; - measurement_type = nullptr; - measurement_value = nullptr; - - init_message(_performative,_sender,_receiver,0,0.0); -} - -void Mqtt_ref_msg::set_pointers() { - - //set the pointer to the elements in data field - //if you change the order or data types of data elements you have to adapt the indices here - performative = &(data[0].i); - sender = &(data[1].i); - receiver = &(data[2].i); - measurement_type = &(data[3].i); - measurement_value = &(data[4].f); -} - -void Mqtt_ref_msg::init_message(int _performative, int _sender, int _receiver, int _measurement_type, double _measurement_value) { - - //add all data and meta elements of this message type - Data_element perf_data; - perf_data.i = _performative; - add_element(perf_data, VILLAS_DATA_TYPE_INT64); - - Data_element sender_data; - sender_data.i = _sender; - add_element(sender_data, VILLAS_DATA_TYPE_INT64); - - Data_element receiver_data; - receiver_data.i = _receiver; - add_element(receiver_data, VILLAS_DATA_TYPE_INT64); - - Data_element measurement_type_data; - measurement_type_data.i = _measurement_type; - add_element(measurement_type_data, VILLAS_DATA_TYPE_INT64); - - Data_element measurement_value_data; - measurement_value_data.f = _measurement_value; - add_element(measurement_value_data, VILLAS_DATA_TYPE_DOUBLE); - - //set the pointers of the message to the corresponding fields in data - set_pointers(); -} - - -void Mqtt_ref_msg::init_meta() { - // returns immediately if static meta information has already been initialized for this message type - //initialize meta info only once - if(!Mqtt_ref_msg::meta_initialized) { - Mqtt_ref_msg::meta_initialized = true; - Mqtt_ref_msg::mqtt_ref_msg_meta.clear(); - - Meta_infos perf_meta; - perf_meta.name = "performative"; - perf_meta.unit = "peformative of this message"; - perf_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_ref_msg::mqtt_ref_msg_meta.push_back(perf_meta); - - Meta_infos sender_meta; - sender_meta.name = "sender"; - sender_meta.unit = "sender of this message"; - sender_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_ref_msg::mqtt_ref_msg_meta.push_back(sender_meta); - - Meta_infos receiver_meta; - receiver_meta.name = "receiver"; - receiver_meta.unit = "receiver of this message"; - receiver_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_ref_msg::mqtt_ref_msg_meta.push_back(receiver_meta); - - Meta_infos measurement_type_meta; - measurement_type_meta.name = "measurement_type"; - measurement_type_meta.unit = "measurement_type of this message"; - measurement_type_meta.type = VILLAS_DATA_TYPE_INT64; - Mqtt_ref_msg::mqtt_ref_msg_meta.push_back(measurement_type_meta); - - Meta_infos measurement_value_meta; - measurement_value_meta.name = "measurement_value"; - measurement_value_meta.unit = "measurement_value of this message"; - measurement_value_meta.type = VILLAS_DATA_TYPE_DOUBLE; - Mqtt_ref_msg::mqtt_ref_msg_meta.push_back(measurement_value_meta); - - } - +Mqtt_ref_msg::Mqtt_ref_msg(int64_t performative, + int64_t sender, + int64_t receiver, + int64_t type, + double value + ) : Villas_message() { + Data_element d1, d2, d3, d4, d5; + d1.i = performative; + d2.i = sender; + d3.i = receiver; + d4.i = type; + d5.f = value; + + data.push_back(d1); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d2); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d3); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d4); + data_types.push_back(VILLASMSG_INTEGER); + data.push_back(d5); + data_types.push_back(VILLASMSG_FLOAT); + length = data.size(); } - -/*! -* \brief Writes the content of a message to a string for debugging -* \return Message content as string -* */ -std::string Mqtt_ref_msg::get_message_output() -{ - std::stringstream temp; - std::string output; - - temp << "Time: " << time_sec - << " Sender: " << *sender - << " Receiver: " << *receiver - << " Performative: " << *performative - << " Type: " << *measurement_type - << " Value: " << *measurement_value; - - output = temp.str(); - return output; -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_reference/mqtt_ref_behavior.cpp b/src/behavior/mqtt_reference/mqtt_ref_behavior.cpp index f5110b5b2b60b0bc2ab86b1db3d8f7b53eb3cef5..209363af147746225a1ed085a9eb7bda81e8db15 100644 --- a/src/behavior/mqtt_reference/mqtt_ref_behavior.cpp +++ b/src/behavior/mqtt_reference/mqtt_ref_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_reference/mqtt_ref_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief constructor * \param _id unique ID of agent @@ -26,11 +25,11 @@ * \param logging indicates if agents logs locally * */ Mqtt_ref_behavior::Mqtt_ref_behavior(int _id, int _type, int _rank, std::string _subtype, double& step_size, - struct data_props _d_props, villas_node_config * _villas_config) + struct data_props _d_props) : Agent_behavior(_id, _type, _subtype, step_size, _d_props) { - vnconfig = _villas_config; + //vnconfig = _villas_config; if(_type == TYPE_DF_INT) { std::string path = "runlog/behavior/agent_DF" + std::to_string(_rank) + ".log"; @@ -41,33 +40,19 @@ Mqtt_ref_behavior::Mqtt_ref_behavior(int _id, int _type, int _rank, std::string IO->init_logging(); } -Mqtt_ref_behavior::~Mqtt_ref_behavior(){ - //destroy_villas_interface is called in agent method - IO->finish_io(); +/*! \brief global initializations (process-wide) for behavior + * \return 0 on success, other number on error + * */ +int Mqtt_ref_behavior::global_init(std::string config_file_path, int rank) { + /*init the global instance and start the node type*/ + return Villas_interface::start_node_type(config_file_path, rank); } - -/*! \brief Initialize the agent behavior - * \param components_ad_nodes [in] vector saving a list of connceted components for each node - * \param connected_nodes [in] vector saving a list of connected nodes for each node - * \param components_file [in] data contained in scenario components input file (integers) - * \param subtypes_file [in] subtypes contained in scenario components input file (strings) - * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) +/*! \brief global cleanup (process-wide) for behavior + * \return 0 on success, other number on error * */ -int Mqtt_ref_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file) { - //set connection parameters - set_connection_params(components_at_nodes); - - //initialize meta information for all message types used in this behavior - Mqtt_ref_msg::init_meta(); - - //Initialize villas interface (important: after init of message meta info!) - int ret = init_villas_interface(vnconfig, Mqtt_ref_msg::mqtt_ref_msg_meta); - return ret; +int Mqtt_ref_behavior::global_cleanup() { + return Villas_interface::stop_node_type(); } @@ -79,26 +64,15 @@ void Mqtt_ref_behavior::process_incoming_messages() { std::list incoming_villas_messages; - villas_interface->receive_messages(incoming_villas_messages); + villas_interface->receive(incoming_villas_messages, 1000, false); while (!incoming_villas_messages.empty()) { - Mqtt_ref_msg mqtt_msg = (Mqtt_ref_msg) incoming_villas_messages.front(); - //set pointers of data to members - mqtt_msg.set_pointers(); - IO->log_info("\tReceived message: " + mqtt_msg.get_message_output()); + auto mqtt_msg = incoming_villas_messages.front(); + IO->log_info("\tReceived message: " + mqtt_msg.toString()); this->process_mqtt_ref_msg(mqtt_msg); incoming_villas_messages.pop_front(); } } - -/*! - * \brief sending function for mqtt messages - * \param msg message to be sent - */ -void Mqtt_ref_behavior::send_villas_msg(Villas_message &msg) -{ - villas_interface->send_message(msg); -} - +#endif diff --git a/src/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.cpp b/src/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.cpp index 6234ad2cd176873bdefabf360ba1011f4f02478d..5b8eec319bca6ff9e1dceb2e936bf34d38073569 100644 --- a/src/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.cpp +++ b/src/behavior/mqtt_reference/mqtt_ref_prosumer_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_reference/mqtt_ref_prosumer_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,27 +26,48 @@ * \param _prosumer_data [in] pointer to prosumer specific datastruct * */ Mqtt_ref_prosumer_behavior::Mqtt_ref_prosumer_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, - Prosumer_data * _prosumer_data) - : Mqtt_ref_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + double& step_size, struct data_props _d_props, Prosumer_data * _prosumer_data) + : Mqtt_ref_behavior(_id, _type, _rank, _subtype, step_size, _d_props), prosumer_data(_prosumer_data) {} - -/*! \brief set connection parameters for this behavior - * \param components_at_nodes provides overview on components connected to nodes +/*! \brief Initialize the agent behavior + * \param components_ad_nodes [in] vector saving a list of connceted components for each node + * \param connected_nodes [in] vector saving a list of connected nodes for each node + * \param components_file [in] data contained in scenario components input file (integers) + * \param subtypes_file [in] subtypes contained in scenario components input file (strings) + * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) * */ -void Mqtt_ref_prosumer_behavior::set_connection_params(std::vector>> * components_at_nodes) { - +int Mqtt_ref_prosumer_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) { + //set connection parameters std::list> node_components = components_at_nodes->at (prosumer_data->node_id-1); int trafo_id = std::get<2>(node_components.front()); //prosumers publish voltage measuerments and subscribe to nothing - vnconfig->type_config.mqtt_conf->subscribe = ""; - vnconfig->type_config.mqtt_conf->publish = "voltage_measurements_trafo" + std::to_string(trafo_id); + //vnconfig->type_config.mqtt_conf->subscribe = ""; + //vnconfig->type_config.mqtt_conf->publish = "voltage_measurements_trafo" + std::to_string(trafo_id); + //Initialize villas interface + std::string custom_param_json_string = "{\"name\": \"agent_" + std::to_string(id) + "\", \"out\": {\"publish\": \"voltage_measurements_trafo" +std::to_string(trafo_id)+ "\"}, \"in\": {\"subscribe\": \"\"}}"; + int ret = init_villas_interface(custom_param_json_string); + if(ret){ + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); + + return 0; } + /*! \brief adjusts control values according to simple rules not requiring communication * */ void Mqtt_ref_prosumer_behavior::execute_agent_behavior() @@ -63,7 +83,7 @@ void Mqtt_ref_prosumer_behavior::execute_agent_behavior() apply_control_values(); } -void Mqtt_ref_prosumer_behavior::process_mqtt_ref_msg(Mqtt_ref_msg &msg) +void Mqtt_ref_prosumer_behavior::process_mqtt_ref_msg(Villas_message &msg) { } @@ -74,14 +94,9 @@ void Mqtt_ref_prosumer_behavior::publish_voltage_measurement() std::complex meas; meas.real(prosumer_data->v_re / (prosumer_data->Vnom / sqrt(3))); meas.imag(prosumer_data->v_im / (prosumer_data->Vnom / sqrt(3))); - Mqtt_ref_msg new_msg; + Mqtt_ref_msg new_msg(FIPA_PERF_INFORM, id, -1, 0, std::abs(meas)); new_msg.time_sec = t_next; - *(new_msg.sender) = id; - *(new_msg.receiver) = -1; - *(new_msg.performative) = FIPA_PERF_INFORM; - *(new_msg.measurement_type) = 0; - *(new_msg.measurement_value) = std::abs(meas); - IO->log_info("\tSend message: " + new_msg.get_message_output()); + IO->log_info("\tSend message: " + new_msg.toString()); send_villas_msg(new_msg); } } @@ -386,3 +401,4 @@ double Mqtt_ref_prosumer_behavior::get_q_available(double p) return q_available; } +#endif \ No newline at end of file diff --git a/src/behavior/mqtt_reference/mqtt_ref_substation_behavior.cpp b/src/behavior/mqtt_reference/mqtt_ref_substation_behavior.cpp index c709e1e2a0dafd74b82a99b73955a6f6c171f57e..79b840ae73cfd0c9aa984fadac202146c568c3dc 100644 --- a/src/behavior/mqtt_reference/mqtt_ref_substation_behavior.cpp +++ b/src/behavior/mqtt_reference/mqtt_ref_substation_behavior.cpp @@ -14,9 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ - +#ifdef WITH_VILLAS #include "behavior/mqtt_reference/mqtt_ref_substation_behavior.h" -#include "villas_interface/villas_interface.h" /*! \brief Constructor * \param _id [in] RepastHPC agent id @@ -27,22 +26,44 @@ * \param _substation_data [in] pointer to substation specific datastruct * */ Mqtt_ref_substation_behavior::Mqtt_ref_substation_behavior(int _id, int _type, int _rank, std::string _subtype, - double& step_size, struct data_props _d_props, villas_node_config * _villas_config, + double& step_size, struct data_props _d_props, Substation_data * _substation_data) - : Mqtt_ref_behavior(_id, _type, _rank, _subtype, step_size, _d_props, _villas_config), + : Mqtt_ref_behavior(_id, _type, _rank, _subtype, step_size, _d_props), substation_data(_substation_data) { voltage_measurements.clear(); } -/*! \brief set connection parameters for this behavior - * \param components_at_nodes provides overview on components connected to nodes +/*! \brief Initialize the agent behavior + * \param components_ad_nodes [in] vector saving a list of connceted components for each node + * \param connected_nodes [in] vector saving a list of connected nodes for each node + * \param components_file [in] data contained in scenario components input file (integers) + * \param subtypes_file [in] subtypes contained in scenario components input file (strings) + * \param el_grid_file [in] electrical connections contained in el. grid input file (integers) * */ -void Mqtt_ref_substation_behavior::set_connection_params( - std::vector>> *components_at_nodes) { +int Mqtt_ref_substation_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, + std::vector>> * connected_nodes, + boost::multi_array *components_file, + boost::multi_array *subtypes_file, + boost::multi_array *el_grid_file) { + //substations subscribe to voltage measurements and publish nothing - vnconfig->type_config.mqtt_conf->subscribe = "voltage_measurements_trafo"+std::to_string(id); - vnconfig->type_config.mqtt_conf->publish = ""; + //vnconfig->type_config.mqtt_conf->subscribe = "voltage_measurements_trafo"+std::to_string(id); + //vnconfig->type_config.mqtt_conf->publish = ""; + //Initialize villas interface + std::string custom_param_json_string = "{\"name\": \"agent_" + std::to_string(id) + "\", \"out\": {\"publish\": \"\"}, \"in\": {\"subscribe\": \"voltage_measurements_trafo" +std::to_string(id) + "\"}}"; + int ret = init_villas_interface(custom_param_json_string); + if(ret){ + return ret; + } + + struct timespec t{}; + t.tv_sec=0; + t.tv_nsec=5000000; + IO->log_info("Waiting for 5ms to make sure connection is ready..."); + nanosleep(&t, nullptr); + + return 0; } /*! \brief Substation reference behavior execution @@ -53,10 +74,10 @@ void Mqtt_ref_substation_behavior::execute_agent_behavior() apply_control_values(); } -void Mqtt_ref_substation_behavior::process_mqtt_ref_msg(Mqtt_ref_msg &msg) +void Mqtt_ref_substation_behavior::process_mqtt_ref_msg(Villas_message &msg) { - int agent_id = *msg.sender; - double voltage = *msg.measurement_value; + int agent_id = msg.data.at(1).i; + double voltage = msg.data.at(4).f; bool update_measurment = false; for (auto &i : voltage_measurements) { @@ -123,3 +144,4 @@ void Mqtt_ref_substation_behavior::apply_control_values() IO->log_info("\tApplying control values\n\t\tn_ctrl: " + std::to_string(substation_data->n_ctrl)); } +#endif \ No newline at end of file diff --git a/src/behavior/ref_intcomm/refic_df_behavior.cpp b/src/behavior/ref_intcomm/refic_df_behavior.cpp index c97c6f64c16a5b8162d5dd7c549c7c93bd6b2328..4e09d1dbd916353d8249a9defa1f2e876be03b30 100644 --- a/src/behavior/ref_intcomm/refic_df_behavior.cpp +++ b/src/behavior/ref_intcomm/refic_df_behavior.cpp @@ -33,14 +33,6 @@ Refic_df_behavior::Refic_df_behavior(int _id, int _type, std::string _subtype, d IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Refic_df_behavior::~Refic_df_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/ref_intcomm/refic_prosumer_behavior.cpp b/src/behavior/ref_intcomm/refic_prosumer_behavior.cpp index 48359490f040593dd5c80cbd98dd8b414bba1a5b..a0839a561527a20bb9ab20a73dbc16a91056d9d0 100644 --- a/src/behavior/ref_intcomm/refic_prosumer_behavior.cpp +++ b/src/behavior/ref_intcomm/refic_prosumer_behavior.cpp @@ -34,14 +34,6 @@ Refic_prosumer_behavior::Refic_prosumer_behavior(int _id, int _type, std::string t_last_query = 0; } -/*! - * \brief Destroy the object (close log file) - */ -Refic_prosumer_behavior::~Refic_prosumer_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/ref_intcomm/refic_slack_behavior.cpp b/src/behavior/ref_intcomm/refic_slack_behavior.cpp index 538ce8c727a5ac93892df21d570f79bfd60de926..5c81add92f7cfd36caba4e2737f2d8e03235aba7 100644 --- a/src/behavior/ref_intcomm/refic_slack_behavior.cpp +++ b/src/behavior/ref_intcomm/refic_slack_behavior.cpp @@ -32,14 +32,6 @@ Refic_slack_behavior::Refic_slack_behavior(int _id, int _type, std::string _subt IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Refic_slack_behavior::~Refic_slack_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/ref_intcomm/refic_substation_behavior.cpp b/src/behavior/ref_intcomm/refic_substation_behavior.cpp index fe05c914053db120eba71292facb1a8bba10ab0d..dfb5ff5faa758d63fb8a0b9a596f1b872f3837da 100644 --- a/src/behavior/ref_intcomm/refic_substation_behavior.cpp +++ b/src/behavior/ref_intcomm/refic_substation_behavior.cpp @@ -33,14 +33,6 @@ Refic_substation_behavior::Refic_substation_behavior(int _id, int _type, std::st IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Refic_substation_behavior::~Refic_substation_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/reference/ref_df_behavior.cpp b/src/behavior/reference/ref_df_behavior.cpp index c4f42e331adb2534f696945ba3df8232800b69eb..94129f5a4d64b3114ec2d3a7423764504f64c465 100644 --- a/src/behavior/reference/ref_df_behavior.cpp +++ b/src/behavior/reference/ref_df_behavior.cpp @@ -33,13 +33,6 @@ Ref_df_behavior::Ref_df_behavior(int _id, int _type, std::string _subtype, doubl IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Ref_df_behavior::~Ref_df_behavior() -{ - IO->finish_io(); -} /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node diff --git a/src/behavior/reference/ref_prosumer_behavior.cpp b/src/behavior/reference/ref_prosumer_behavior.cpp index 258f6741e056627f24ab9c779fa1b7bcdb258974..c06dd17c0f13585918de7c184aa01bebe15fa2bd 100644 --- a/src/behavior/reference/ref_prosumer_behavior.cpp +++ b/src/behavior/reference/ref_prosumer_behavior.cpp @@ -33,14 +33,6 @@ Ref_prosumer_behavior::Ref_prosumer_behavior(int _id, int _type, std::string _su IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Ref_prosumer_behavior::~Ref_prosumer_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/reference/ref_slack_behavior.cpp b/src/behavior/reference/ref_slack_behavior.cpp index 3a803827e93ba99f9a127ccddf07876b09de3558..fbe927924706b7763992683ddba50bdc81b4ae52 100644 --- a/src/behavior/reference/ref_slack_behavior.cpp +++ b/src/behavior/reference/ref_slack_behavior.cpp @@ -32,14 +32,6 @@ Ref_slack_behavior::Ref_slack_behavior(int _id, int _type, std::string _subtype, IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Ref_slack_behavior::~Ref_slack_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/reference/ref_substation_behavior.cpp b/src/behavior/reference/ref_substation_behavior.cpp index 980983bbe6db136e72e0fb066f24e6c290296b3f..4e897f6f45cae3b3da8ca33d8ea7df542058cc8c 100644 --- a/src/behavior/reference/ref_substation_behavior.cpp +++ b/src/behavior/reference/ref_substation_behavior.cpp @@ -33,14 +33,6 @@ Ref_substation_behavior::Ref_substation_behavior(int _id, int _type, std::string IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Ref_substation_behavior::~Ref_substation_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/swarmgrid/swarm_df_behavior.cpp b/src/behavior/swarmgrid/swarm_df_behavior.cpp index 325d1683b03a29d22bb404582edd3724c5684a2a..e1b7b341439aeb225566d44a86fbce8089c250db 100644 --- a/src/behavior/swarmgrid/swarm_df_behavior.cpp +++ b/src/behavior/swarmgrid/swarm_df_behavior.cpp @@ -37,14 +37,6 @@ Swarm_df_behavior::Swarm_df_behavior(int _id, int _type, std::string _subtype, IO->init_logging(); } -/*! - * \brief Destroy the object (close log file) - */ -Swarm_df_behavior::~Swarm_df_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.cpp b/src/behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.cpp deleted file mode 100644 index 1b613481529a86c552a58845fa6843344724f186..0000000000000000000000000000000000000000 --- a/src/behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/** - * This file is part of DistAIX - * - * 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 . - *********************************************************************************/ - -#include "behavior/swarmgrid/swarm_dpsim_cosim_slack_behavior.h" -#include "villas_interface/villas_interface.h" -#include -#include - -Swarm_dpsim_cosim_slack_behavior::Swarm_dpsim_cosim_slack_behavior(int _id, int _type, int _rank, std::string _subtype, double& _step_size, struct data_props _d_props, - Slack_data * _slack_data, villas_node_config * _villas_config, bool _realtime, bool _sync) - : Swarm_slack_behavior(_id, _type, _subtype, step_size, _d_props, _slack_data) -{ - // IO Logging started in inheritance chain of Swarm_slack_behavior?! - vnconfig = _villas_config; - - sender = _id; - step_size = _step_size; - realtime = _realtime; - sync = _sync; -} - -Swarm_dpsim_cosim_slack_behavior::~Swarm_dpsim_cosim_slack_behavior() { - - IO->log_info("Number of sent messages: " + std::to_string(numOfSentMessages)); - IO->log_info("Number of received messages: " + std::to_string(numOfReceivedMessages)); - - // IO Logging finised in inheritance chain of Swarm_slack_behavior?! -} - - -// Methods from dpsim_cosim_behavior -void Swarm_dpsim_cosim_slack_behavior::create_endpoints(villas_node_config * _vnconfig, std::string agent_id) { - std::list communication_patterns; - // Copy name of agent and remove "agent_" - std::list *_in_endpoints = &_vnconfig->type_config.nanomsg_conf->in_endpoints; - std::list *_out_endpoints = &_vnconfig->type_config.nanomsg_conf->out_endpoints; - - IO->log_info("In_endpoints:"); - for(auto i : *_in_endpoints) - IO->log_info(i); - - IO->log_info("Out_endpoints:"); - for(auto i : *_out_endpoints) - IO->log_info(i); - -} - -// Methods from dpsim_cosim_slack_behavior -void Swarm_dpsim_cosim_slack_behavior::send_villas_msg(Dpsim_cosim_msg message){ - numOfSentMessages++; - - IO->log_info("\tSend message: " + message.get_message_output()); - villas_interface->send_message(message); - -} - -void Swarm_dpsim_cosim_slack_behavior::synchronize_with_remote(){ - - bool remove_msg_overhead = false; - - IO->log_info("###### Start synchronization with remote..."); - Dpsim_cosim_msg out_msg, in_msg; - std::list incoming_villas_messages; - - IO->log_info("Waiting for answer..."); - busy_receive_msg(&incoming_villas_messages); - send_villas_msg(out_msg); - - // process incoming message - if (!incoming_villas_messages.empty()) { - if(incoming_villas_messages.size() > 1){ - IO->log_info("WARNING: More than one sync message received... (" - + std::to_string(incoming_villas_messages.size()) + ")"); - } - in_msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); - // set pointer of data to members - in_msg.set_pointers(); - - incoming_villas_messages.pop_front(); - - IO->log_info("Answer received..."); - IO->log_info("\tSync.in_re = " + std::to_string(in_msg.value->real())); - IO->log_info("\tSync.in_im = " + std::to_string(in_msg.value->imag())); - } - else { - IO->log_info("ERROR IN SYNCHRONIZE_WITH_REMOTE! BUSY WAITING RETURNED BUT NO RESPONSE COULD BE READ"); - } - - if (remove_msg_overhead) { - IO->log_info("Additional removal of second synchronization message of dpsim triggered..."); - IO->log_info("Be careful with this option, as the removal of the CORRECT message cannot be guaranteed..."); - - IO->log_info("Waiting for answer..."); - IO->log_info("Wait 5secs before reading socket again..."); - sleep(5); - busy_receive_msg(&incoming_villas_messages); - - // process incoming message - if (incoming_villas_messages.size() >= 1) { - if(incoming_villas_messages.size() > 1){ - IO->log_info("WARNING: More than one sync message received... (" - + std::to_string(incoming_villas_messages.size()) + ")"); - } - in_msg = (Dpsim_cosim_msg) incoming_villas_messages.front(); - // set pointer of data to members - in_msg.set_pointers(); - - incoming_villas_messages.pop_front(); - - IO->log_info("Answer received..."); - IO->log_info("\tSync2.in_re = " + std::to_string(in_msg.value->real())); - IO->log_info("\tSync2.in_im = " + std::to_string(in_msg.value->imag())); - } - } -} - -int Swarm_dpsim_cosim_slack_behavior::initialize_agent_behavior(std::vector>> * components_at_nodes, - std::vector>> * connected_nodes, - boost::multi_array *components_file, - boost::multi_array *subtypes_file, - boost::multi_array *el_grid_file) { - - // Initialize swarm behavior - int ret = Swarm_slack_behavior::initialize_agent_behavior(components_at_nodes, connected_nodes, components_file, subtypes_file, el_grid_file); - if (ret){ - return ret; - } - - // Initialize cosim behavior - // Initialize meta information for all message types used in this behavior - Dpsim_cosim_msg::init_meta(); - if(vnconfig->type_name == "nanomsg"){ - IO->log_info("Create Endpoints..."); - create_endpoints(vnconfig, std::to_string(sender)); - } - else if(vnconfig->type_name == "mqtt") { - IO->log_info("Set connection parameters..."); - vnconfig->type_config.mqtt_conf->subscribe = "dpsim->dist"; - vnconfig->type_config.mqtt_conf->publish = "dist->dpsim"; - } - else { - IO->log_info("ERROR: '" + vnconfig->type_name + "' is no valid type for cosim behavior..."); - } - - // Initialize villas interface (important: after init of message meta info!) - IO->log_info("Init VILLAS interface..."); - ret = init_villas_interface(vnconfig, Dpsim_cosim_msg::dpsim_cosim_message_meta); - if (ret){ - return ret; - } - - if(sync){ - synchronize_with_remote(); - } - return 0; -} - -void Swarm_dpsim_cosim_slack_behavior::report_to_superior_grid(Dpsim_cosim_msg message, std::list *incoming_villas_messages){ - IO->log_info("###### Execute dpsim_cosim behavior... "); - send_villas_msg(message); - - if(realtime){ - IO->log_info("[REALTIME] Try to read new message..."); - receive_message(incoming_villas_messages); - } - else { - IO->log_info("Wait until message arrives..."); - int ret = busy_receive_msg(incoming_villas_messages); - if(ret == 1) { - // early simulation stop signalized - vnconfig->stop_at = repast::RepastProcess::instance()->getScheduleRunner().currentTick(); - std::cout << std::endl << "Cosimulation-timeout reached! Stopping simulation..." << std::endl; - } - } -} - -void Swarm_dpsim_cosim_slack_behavior::receive_message(std::list *incoming_villas_messages){ - numOfReceivedMessages++; - - villas_interface->receive_messages(*incoming_villas_messages); - if(!incoming_villas_messages->empty()){ - IO->log_info("Message received... " + std::to_string(incoming_villas_messages->size())); - } -} - -int Swarm_dpsim_cosim_slack_behavior::busy_receive_msg(std::list *incoming_villas_messages){ - bool message_removal = false; - numOfReceivedMessages++; - // TODO: Do not cancel in first step!!... - auto start = std::chrono::steady_clock::now(); - while(incoming_villas_messages->empty()) { - // If timeout reached, return 1 to signalize early simulation stop - if (std::chrono::duration_cast(std::chrono::steady_clock::now()-start).count() >= timeout) - return 1; - - villas_interface->receive_messages(*incoming_villas_messages); - } - if(!incoming_villas_messages->empty()) { - IO->log_info("Message received..."); - - if(incoming_villas_messages->size() > 1 && message_removal){ - IO->log_info("More than one message received!"); - - auto it = incoming_villas_messages->begin(); - std::advance(it, incoming_villas_messages->size() - 1); - incoming_villas_messages->erase(incoming_villas_messages->begin(), it); // Complexity linear with number of erased elements - - IO->log_info("Reduced down to: " + std::to_string(incoming_villas_messages->size())); - } - } - - // if(first_step) - // first_step = false; - // auto stop = std::chrono::steady_clock::now(); - // IO->log_info("Time in busy_receive_msg() = " + std::to_string(std::chrono::duration_cast(stop-start).count())); - return 0; -} \ No newline at end of file diff --git a/src/behavior/swarmgrid/swarm_prosumer_behavior.cpp b/src/behavior/swarmgrid/swarm_prosumer_behavior.cpp index 8ec11341d34442e16a5c0a5da90c27ef55ac64f8..d004837f8fc15ee52b623d4adb1d9cb279399873 100644 --- a/src/behavior/swarmgrid/swarm_prosumer_behavior.cpp +++ b/src/behavior/swarmgrid/swarm_prosumer_behavior.cpp @@ -34,14 +34,6 @@ Swarm_prosumer_behavior::Swarm_prosumer_behavior(int _id, int _type, std::string { } -/*! - * \brief Destroy the object (close log file) - */ -Swarm_prosumer_behavior::~Swarm_prosumer_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/swarmgrid/swarm_slack_behavior.cpp b/src/behavior/swarmgrid/swarm_slack_behavior.cpp index 01a2d124c3ac3bb4b9ccb8b50b16220dc8d26144..5e613d5d66f1da01c6a1c17005d1edecf1a08432 100644 --- a/src/behavior/swarmgrid/swarm_slack_behavior.cpp +++ b/src/behavior/swarmgrid/swarm_slack_behavior.cpp @@ -34,14 +34,6 @@ Swarm_slack_behavior::Swarm_slack_behavior(int _id, int _type, std::string _subt { } -/*! - * \brief Destroy the object (close log file) - */ -Swarm_slack_behavior::~Swarm_slack_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node * \param connected_nodes [in] vector saving a list of connected nodes for each node diff --git a/src/behavior/swarmgrid/swarm_substation_behavior.cpp b/src/behavior/swarmgrid/swarm_substation_behavior.cpp index 3661b7a0b9c2f3aa3c65a20312929b812821b73a..53113fc0a35787613ba8c5618cdb05f0f3013237 100644 --- a/src/behavior/swarmgrid/swarm_substation_behavior.cpp +++ b/src/behavior/swarmgrid/swarm_substation_behavior.cpp @@ -34,14 +34,6 @@ Swarm_substation_behavior::Swarm_substation_behavior(int _id, int _type, std::st { } -/*! - * \brief Destroy the object (close log file) - */ -Swarm_substation_behavior::~Swarm_substation_behavior() -{ - IO->finish_io(); -} - /*! \brief Initialize the agent behavior * \param components_ad_nodes [in] vector saving a list of connceted components for each node diff --git a/src/edges/cable.cpp b/src/edges/cable.cpp index b10a972d0b1c11646c919cfbb062172490832901..04f01ad41b99e7ccb1f384c5f6e7786d49de06fa 100644 --- a/src/edges/cable.cpp +++ b/src/edges/cable.cpp @@ -61,6 +61,7 @@ Cable::Cable( Cable::~Cable() { IO->finish_io(); + delete IO; } diff --git a/src/model/model.cpp b/src/model/model.cpp index 7f85c215ff6178aed8bb0181f7103f09300090e8..eb1a7c4187c605140e2d1adedeccc08a991dfe25 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -22,7 +22,9 @@ #include #include "model/config.h" #include "model/model.h" -#include "villas_interface/villas_interface.h" +#ifdef WITH_VILLAS +#include "behavior/dpsim_cosim/dpsim_cosim_behavior.h" +#endif BOOST_CLASS_EXPORT_GUID(repast::SpecializedProjectionInfoPacket >, "SpecializedProjectionInfoPacket_EDGE"); @@ -83,8 +85,12 @@ Model::Model(std::string &propsFile, int argc, char** argv, boost::mpi::communic //initialize counter variables for FBS IO->reset_loop_counters(); - // read villas configuration parameters from model.props file - read_villas_config(); + // global init of agent behavior type (agent-independent, static function call) + int ret = global_behavior_init(); + if (ret){ + IO->log_info("ERROR on global behavior init, aborting: return value is: " + std::to_string(ret)); + do_exit(ret); + } // Create Message Router and Directory Facilitator agents create_MR_DF_agents(); @@ -98,40 +104,24 @@ Model::~Model(){ IO->finish_time_measurements(stop_at); - if(behavior_type == CTRL_MQTT_TEST - || behavior_type == CTRL_MQTT_PINGPONG - || behavior_type == CTRL_MQTT_HIGHLOAD - || behavior_type == CTRL_ENSURE - || behavior_type == CTRL_DPSIM_COSIM_REF - || behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX){ - //disconnect villas_interface of all all agents - for(auto a : local_agents){ - IO->log_info("Disconnecting agent " + IO->id2str(a->getId())); - int ret = a->villas_interface_disconnect(); - if (ret) { - IO->log_info("Error upon disconnecting agent " + IO->id2str(a->getId()) + ": " + std::to_string(ret)); - } - } - struct timespec t; - t.tv_sec = 0; - t.tv_nsec = 1000000; // 1 ms for all disconnections to complete - nanosleep(&t, nullptr); - - //Stop the villas node type before deleting IO - interface->stop_node_type(); - delete villas_config_agents; - delete villas_config_node_disabled; - delete interface; + // agents and network are deleted via context - } + //Process-wide clean-up of behaviors (close interfaces etc.) + IO->log_info("Global behavior cleanup"); + global_behavior_cleanup(); + IO->log_info("deleting agent creator"); delete creator; - delete props; + IO->log_info("deleting agent provider"); delete provider; + IO->log_info("deleting agent receiver"); delete receiver; - if(rank == 0) - delete progress_p; + + if(rank == 0) { + IO->log_info("deleting progress bar"); + delete progress_p; + } if(behavior_type != CTRL_NON_INTELLIGENT && use_commdata) { //free shared memory variables only if not in non-intelligent case @@ -140,10 +130,14 @@ Model::~Model(){ MPI_Comm_free(&MR_comm); } + IO->log_info("deleting shared MPI window for agent-rank-relation"); MPI_Win_free(&shared_mem_window_agent_rank_relation); + IO->log_info("deleting MPI communicator for agent-rank-relation"); MPI_Comm_free(&agent_rank_relation_comm); + IO->log_info("finishing IO"); IO->finish_io(); + delete props; delete IO; } @@ -196,8 +190,13 @@ void Model::init() { IO->stop_time_measurement(IO->tm_init); /*Initialize progess bar in rank 0*/ - if(rank == 0) - progress_p = new boost::progress_display( stop_at ); + if(rank == 0) { +#if (BOOST_VERSION >= 107200) + progress_p = new boost::timer::progress_display(stop_at); +#else + progress_p = new boost::progress_display(stop_at); +#endif + } /*Write some time measurement results of initialization*/ IO->log_info("############## INIT FINISHED - TIME MEASUREMENTS ###################"); @@ -315,13 +314,20 @@ void Model::step() { // IO->flush_db(); //} +#ifdef WITH_VILLAS // During co-simulation, the rank including the slack-agent can decide to terminate // the simulation early, i.e. before all time steps are simulated. // In order to terminate the whole simulation properly, the schedulers of all ranks have to // synchronized if (behavior_type == CTRL_DPSIM_COSIM_REF || behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX){ - synchronize_schedulers(); + IO->log_info("Synchronizing Scheduler"); + double new_stop_at = Dpsim_cosim_behavior::global_step((double) stop_at, agent_rank_relation[0], world_size); + stop_at = (unsigned long) new_stop_at; + repast::RepastProcess::instance()->getScheduleRunner().scheduleStop((double) stop_at); + IO->log_info("Simulation will stop at tick: " + std::to_string(stop_at)); + //synchronize_schedulers(); } +#endif IO->stop_time_measurement(IO->tm_tick); @@ -447,28 +453,6 @@ void Model::process_agent_messages() { } -/*! \brief synchronizes stop_at of all schedulers to that of rank0 - * - * The function sets the stop_at variable of the scheduler to the value - * defined in villas_config_agents and synchronizes all schedulers - * to that of rank0 - * - * */ -void Model::synchronize_schedulers(){ - double curr_stop_at = villas_config_agents->stop_at; - if(world_size > 1){ - IO->log_info("Synchronizing Scheduler"); - MPI_Bcast(&curr_stop_at, 1, MPI_DOUBLE, agent_rank_relation[0], MPI_COMM_WORLD); - if(curr_stop_at != stop_at){ - IO->log_info("New value for stop_at received = " + std::to_string(curr_stop_at)); - stop_at = curr_stop_at; - repast::RepastProcess::instance()->getScheduleRunner().scheduleStop(stop_at); - } - } - - -} - /*! \brief exit the simulation (called in error case) * \param code Integer giving the the code of the error that happend * diff --git a/src/model/model_config.cpp b/src/model/model_config.cpp index 22f84ec44c2060a8e98fe83af1afbb8428ef7a01..839f272b2dd5dbd3a763077ea749a1f67f2e0141 100644 --- a/src/model/model_config.cpp +++ b/src/model/model_config.cpp @@ -16,7 +16,13 @@ *********************************************************************************/ #include "model/model.h" -#include "villas_interface/villas_interface.h" +#ifdef WITH_VILLAS + #include "behavior/dpsim_cosim/dpsim_cosim_behavior.h" + #include "behavior/mqtt_reference/mqtt_ref_behavior.h" + #include "behavior/mqtt_highload/mqtt_highload_behavior.h" + #include "behavior/mqtt_pingpong/mqtt_pingpong_behavior.h" + #include "behavior/ensure/ensure_behavior.h" +#endif /*! \brief Read all properties of the model from the provided model.props file * and save them to member variables @@ -114,100 +120,68 @@ void Model::read_model_props(){ } } -/*! \brief Read all villas configuration parameters from the model.props file - * depending on the selected behavior +/*! \brief Global init of behavior + * \return 0 on success, other value on error + * */ -void Model::read_villas_config() { - - //create villas config with disabled villas node (used in all agents that never contain a villas node) - villas_config_node_disabled = new villas_node_config(); - villas_config_node_disabled->with_node = false; - villas_config_node_disabled->type_name = ""; - villas_config_node_disabled->format_name = ""; - villas_config_node_disabled->loglevel = ""; - villas_config_agents = villas_config_node_disabled; //set the villas node to disabled per default - - if (behavior_type == CTRL_MQTT_TEST || - behavior_type == CTRL_MQTT_PINGPONG || - behavior_type == CTRL_MQTT_HIGHLOAD || - behavior_type == CTRL_ENSURE || - behavior_type == CTRL_DPSIM_COSIM_REF || - behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX) { - - // we are using a behavior that needs villas node(s) - - // set all config params for villas interface of model that are independent of node type - villas_config_model = new villas_node_config(); - villas_config_model->type_name = props->getProperty("villas.nodetype"); - villas_config_model->format_name = props->getProperty("villas.format"); - villas_config_model->loglevel = props->getProperty("villas.loglevel"); - villas_config_model->with_node = false; - villas_config_model->stop_at = stop_at; - - // villas node configs for agents (independent of node type) - villas_config_agents = new villas_node_config(); - villas_config_agents->type_name = villas_config_model->type_name; - villas_config_agents->format_name = villas_config_model->format_name; - villas_config_agents->loglevel = villas_config_model->loglevel; - villas_config_agents->with_node = true; - villas_config_agents->stop_at = villas_config_model->stop_at; +int Model::global_behavior_init() { - //parse the properties of the node type configuration for the agents - if (villas_config_model->type_name == "mqtt" ) { - - IO->log_info("Reading VILLAS config for MQTT"); - villas_config_agents->type_config.mqtt_conf = new mqtt_data(); - villas_config_agents->type_config.mqtt_conf->broker = props->getProperty( - "villas.mqtt.broker"); - villas_config_agents->type_config.mqtt_conf->port = repast::strToInt( - props->getProperty("villas.mqtt.port")); - villas_config_agents->type_config.mqtt_conf->qos = repast::strToInt( - props->getProperty("villas.mqtt.qos")); - villas_config_agents->type_config.mqtt_conf->retain = repast::strToInt( - props->getProperty("villas.mqtt.retain")); - villas_config_agents->type_config.mqtt_conf->keepalive = repast::strToInt( - props->getProperty("villas.mqtt.keepalive")); - villas_config_agents->type_config.mqtt_conf->subscribe = props->getProperty( - "villas.mqtt.subscribe"); - villas_config_agents->type_config.mqtt_conf->publish = props->getProperty( - "villas.mqtt.publish"); - // MQTT ssl params - villas_config_agents->type_config.mqtt_conf->ssl_enabled = repast::strToInt( - props->getProperty("villas.mqtt.ssl_enabled")); - villas_config_agents->type_config.mqtt_conf->ssl_insecure = repast::strToInt( - props->getProperty("villas.mqtt.ssl_insecure")); - villas_config_agents->type_config.mqtt_conf->ssl_cert_reqs = repast::strToInt( - props->getProperty("villas.mqtt.ssl_cert_reqs")); - villas_config_agents->type_config.mqtt_conf->ssl_cafile = props->getProperty( - "villas.mqtt.ssl_cafile"); - villas_config_agents->type_config.mqtt_conf->ssl_capath = props->getProperty( - "villas.mqtt.ssl_capath"); - villas_config_agents->type_config.mqtt_conf->ssl_certfile = props->getProperty( - "villas.mqtt.ssl_certfile"); - villas_config_agents->type_config.mqtt_conf->ssl_keyfile = props->getProperty( - "villas.mqtt.ssl_keyfile"); - villas_config_agents->type_config.mqtt_conf->ssl_ciphers = props->getProperty( - "villas.mqtt.ssl_ciphers"); - villas_config_agents->type_config.mqtt_conf->ssl_tls_version = props->getProperty( - "villas.mqtt.ssl_tls_version"); - - } else if (villas_config_model->type_name == "nanomsg") { - - IO->log_info("Reading VILLAS config for nanomsg"); - villas_config_agents->type_config.nanomsg_conf = new nanomsg_data(); - villas_config_agents->type_config.nanomsg_conf->in_endpoints.push_back(props->getProperty( - "villas.nanomsg.in_endpoints")); - villas_config_agents->type_config.nanomsg_conf->out_endpoints.push_back(props->getProperty( - "villas.nanomsg.out_endpoints")); + std::string config_file_path = props->getProperty("villas.configfile"); + switch (behavior_type) { +#ifdef WITH_VILLAS + case CTRL_DPSIM_COSIM_REF: { + return Dpsim_cosim_behavior::global_init(config_file_path, (double) stop_at, rank); + } + case CTRL_DPSIM_COSIM_SWARMGRIDX: { + return Dpsim_cosim_behavior::global_init(config_file_path, (double) stop_at, rank); + } + case CTRL_MQTT_PINGPONG : { + return Mqtt_pingpong_behavior::global_init(config_file_path, rank); + } + case CTRL_MQTT_HIGHLOAD : { + return Mqtt_highload_behavior::global_init(config_file_path, rank); } + case CTRL_MQTT_TEST : { + return Mqtt_ref_behavior::global_init(config_file_path, rank); + } + case CTRL_ENSURE : { + return Ensure_behavior::global_init(config_file_path, rank); + } +#endif + default: { + //nothing + return 0; + } + } +} - // start the node type in this process - std::vector empty_meta(0); - interface = new Villas_interface(villas_config_model, IO, - "rank_" + std::to_string(rank), empty_meta); - IO->log_info("Starting villas node type"); - interface->start_node_type(); +int Model::global_behavior_cleanup() { + switch (behavior_type) { +#ifdef WITH_VILLAS + case CTRL_DPSIM_COSIM_REF: { + return Dpsim_cosim_behavior::global_cleanup(); + } + case CTRL_DPSIM_COSIM_SWARMGRIDX: { + return Dpsim_cosim_behavior::global_cleanup(); + } + case CTRL_MQTT_PINGPONG : { + return Mqtt_pingpong_behavior::global_cleanup(); + } + case CTRL_MQTT_HIGHLOAD : { + return Mqtt_highload_behavior::global_cleanup(); + } + case CTRL_MQTT_TEST : { + return Mqtt_ref_behavior::global_cleanup(); + } + case CTRL_ENSURE : { + return Ensure_behavior::global_cleanup(); + } +#endif + default: { + //nothing + return 0; + } } } diff --git a/src/model/model_init_agents.cpp b/src/model/model_init_agents.cpp index c7367ca34196dcb0f055dee34795a8e071bdf229..5749d374b37b093912290b8fdd969674ab1c3f25 100644 --- a/src/model/model_init_agents.cpp +++ b/src/model/model_init_agents.cpp @@ -35,7 +35,7 @@ void Model::create_MR_DF_agents(){ d_props_DF.result.loglevel = loglevel; d_props_DF.result.db_enabled = results_db_agents || results_db_ranks || results_db_cables; d_props_DF.result.dbconn = d_props.result.dbconn; - DF_agent = new Directoryfacilitator_agent(df_id, true, step_size, behavior_type, model_type,st, d_props_DF, villas_config_node_disabled); + DF_agent = new Directoryfacilitator_agent(df_id, true, step_size, behavior_type, model_type,st, d_props_DF); context.addAgent(DF_agent); IO->log_info("Creating MR agent"); @@ -50,7 +50,7 @@ void Model::create_MR_DF_agents(){ d_props_MR.result.loglevel = loglevel; d_props_MR.result.db_enabled = results_db_agents || results_db_ranks || results_db_cables; d_props_MR.result.dbconn = d_props.result.dbconn; - MR_agent = new Messagerouter_agent(mr_id, true, step_size, behavior_type, model_type, st, d_props_MR, villas_config_node_disabled, use_commdata); + MR_agent = new Messagerouter_agent(mr_id, true, step_size, behavior_type, model_type, st, d_props_MR, use_commdata); context.addAgent(MR_agent); } @@ -221,25 +221,6 @@ void Model::init_agent_behaviors() { } - //wait here for fixed amount of time to be sure that all VILLAS connections are ready to be used - if (behavior_type == CTRL_MQTT_TEST || - behavior_type == CTRL_ENSURE || - behavior_type == CTRL_MQTT_PINGPONG || - behavior_type == CTRL_MQTT_HIGHLOAD || - behavior_type == CTRL_DPSIM_COSIM_REF || - behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX){ - - struct timespec t; - t.tv_sec=1; - t.tv_nsec=0; - if(rank == 0){ - std::cout << " +++++++ Waiting for " << t.tv_sec << " sec and " << t.tv_nsec << - " ns to make sure all VILLASnode connections are ready +++++++" << std::endl; - } - nanosleep(&t, nullptr); - } - - IO->stop_time_measurement(IO->tm_comm_partners_init); if(rank == 0) { @@ -311,6 +292,7 @@ void Model::agent_creator(repast::AgentId &id, std::string &_subtype, int &node_ if (id.agentType() == TYPE_SLACK_INT) { if(behavior_type == CTRL_DPSIM_COSIM_REF ||behavior_type == CTRL_DPSIM_COSIM_SWARMGRIDX){ +#ifdef WITH_VILLAS if(param[0] == 0.0 && param[1] == 0.0){ std::cout << "#########################################################################################" << std::endl; std::cout << "WARNING: Co-simulation behavior was chosen, but Slack was initialized with V = Complex(0,0)" << std::endl; @@ -318,19 +300,22 @@ void Model::agent_creator(repast::AgentId &id, std::string &_subtype, int &node_ } auto * agent = new Slack_agent(id, true, step_size, std::stod(_subtype), param[0], param[1], behavior_type, model_type, _subtype, d_props_agent, - villas_config_agents, _ict_connectivity, realtime); + _ict_connectivity, realtime); context.addAgent(agent); +#else + std::cout << "Slack agent creation: Chosen behavior type not available without VILLASnode support! Check config!"; + do_exit(-1); +#endif } else { auto * agent = new Slack_agent(id, true, step_size, std::stod(_subtype), behavior_type, model_type, _subtype, d_props_agent, - villas_config_agents, _ict_connectivity); + _ict_connectivity); context.addAgent(agent); } } else if (id.agentType() == TYPE_TRANSFORMER_INT) { auto *agent = new Transformer_agent(id, true, step_size, node_id, behavior_type, model_type, _subtype, d_props_agent, - villas_config_agents, param[0], param[1], param[2], param[3], param[4], (int) param[5], (int) param[6], _ict_connectivity); @@ -338,7 +323,6 @@ void Model::agent_creator(repast::AgentId &id, std::string &_subtype, int &node_ } else if (id.agentType() == TYPE_NODE_INT) { auto *agent = new Node_agent(id, true, step_size, param[0], behavior_type, model_type, _subtype, d_props_agent, - villas_config_agents, (int) param[1], _ict_connectivity); context.addAgent(agent); } else { @@ -389,7 +373,7 @@ void Model::agent_creator(repast::AgentId &id, std::string &_subtype, int &node_ } auto *agent = new Prosumer_agent(id, true, step_size, behavior_type, model_type, - &component_profiles, interpolation_type, d_props_agent, villas_config_agents, prosumer_data); + &component_profiles, interpolation_type, d_props_agent, prosumer_data); context.addAgent(agent); } } diff --git a/src/model/model_io.cpp b/src/model/model_io.cpp index dd96e2b41b6d7fe0c1b470b380dd818f2d03ad38..d805db25ec5eea1904407243ea5bf5b788d8ed4b 100644 --- a/src/model/model_io.cpp +++ b/src/model/model_io.cpp @@ -637,27 +637,9 @@ void ModelIO::print_model_configuration() { std::cout << "db.dbname\t\t\t=\t" << props->getProperty("db.dbname") << std::endl; } - if(props->getProperty("ctrl.type") == "2" || props->getProperty("ctrl.type") == "4"){ - std::cout << "############################## VILLAS CONFIG #####################################" << std::endl; - std::cout << "villas.format\t\t\t=\t" << props->getProperty("villas.format") << std::endl; - - std::cout << "villas.mqtt.broker\t\t=\t" << props->getProperty("villas.mqtt.broker") << std::endl; - std::cout << "villas.mqtt.port\t\t=\t" << props->getProperty("villas.mqtt.port") << std::endl; - std::cout << "villas.mqtt.qos\t\t\t=\t" << props->getProperty("villas.mqtt.qos") << std::endl; - std::cout << "villas.mqtt.retain\t\t=\t" << props->getProperty("villas.mqtt.retain") << std::endl; - std::cout << "villas.mqtt.ssl_enabled\t\t=\t" << props->getProperty("villas.mqtt.ssl_enabled") << std::endl; - std::cout << "villas.mqtt.keepalive\t\t=\t" << props->getProperty("villas.mqtt.keepalive") << std::endl; - std::cout << "villas.mqtt.user\t\t=\t" << props->getProperty("villas.mqtt.user") << std::endl; - std::cout << "villas.mqtt.password\t\t=\t" << props->getProperty("villas.mqtt.password") << std::endl; - - } else if (props->getProperty("ctrl.type") == "3"){ - std::cout << "############################## VILLAS CONFIG #####################################" << std::endl; - std::cout << "villas.format\t\t\t=\t" << props->getProperty("villas.format") << std::endl; - // TODO add nanomsg specific config here - } - + std::cout << "############################## VILLAS CONFIG #####################################" << std::endl; + std::cout << "villas.configfile\t\t\t=\t" << props->getProperty("villas.configfile") << std::endl; std::cout << "######################################################################################" << std::endl; - std::cout.flush(); } diff --git a/src/villas_interface/villas_interface.cpp b/src/villas_interface/villas_interface.cpp deleted file mode 100644 index c6edf8467fd6bd5ca5becb76c8b7c51214053774..0000000000000000000000000000000000000000 --- a/src/villas_interface/villas_interface.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/** - * This file is part of DistAIX - * - * 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 . - *********************************************************************************/ - - -#include "villas_interface/villas_interface.h" - -#include -#include -#include "model/io_object.h" - - -#ifdef WITH_VILLAS - #include "villas/nodes/mqtt.hpp" - #include "villas/nodes/nanomsg.hpp" - #include "villas/node.h" - #include "villas/format.hpp" - #include "villas/signal.h" - #include "villas/log.hpp" -#endif - - - -/*! \brief Constructor of Villas_interface class - * - * */ -Villas_interface::Villas_interface(villas_node_config *_config, IO_object *IO_obj, std::string _name, std::vector &_meta) { - - - IO = IO_obj; //use IO object of holing instance - IO->log_info("Villas_interface: constructor for node " + _name); - -#ifdef WITH_VILLAS - meta = _meta; - number_of_sent_messages = 0; - with_node = _config->with_node; - - //ranks set logging properties for VILLASnode lib - if(_name.find("rank_") != std::string::npos){ - json_t *json_logging; - json_error_t * j_err = nullptr; - - // available log levels of VILLASnode lib: - // trace : ??? - // debug : log debug messages - // info : log info messages - // warning : log warnings - // error : log error messages - // critical : ??? - // off : no logging at all - - //json_logging = json_loads("{\"level\" : \"warning\", \"file\" : \"villas.log\"}", 0, j_err); - std::string params = R"({"level" : ")" + _config->loglevel + "\"}"; - json_logging = json_loads(params.c_str(), 0, j_err); - - villas::logging.parse(json_logging); - - } - - //lookup node type - IO->log_info("Villas_interface: Node type lookup for node " + _name + " Type: " + _config->type_name + "."); - type = node_type_lookup(_config->type_name); - if(type== nullptr){ - IO->log_info("Villas_interface: ERROR: something went wrong in node type lookup"); - throw std::runtime_error("Villas_interface: node_type_lookup failed for type " + _config->type_name); - } - - if(with_node) { - int ret; //for return values of villas functions - - //set several states of node internal objects to STATE_DESTROYED - n = (struct vnode*) malloc(sizeof(struct vnode)); - n->state = State::DESTROYED; - n->in.state = State::DESTROYED; - n->out.state = State::DESTROYED; - n->in.signals.state = State::DESTROYED; - n->out.signals.state = State::DESTROYED; - - //Init memory pool for this node (used to get memory for sample in send_message) - p = (struct pool*) malloc(sizeof(struct pool)); - p->state = State::DESTROYED; - p->queue.state = State::DESTROYED; - //Allocate 1MB of pool memory for sent and received messages - //200 kiByte = 204800 - //1 MiB = 1048576 - size_t blocksize=SAMPLE_LENGTH(meta.size()); //sizeof(struct sample) + meta.size()* sizeof(double); - IO->log_info("Villas_interface: Memory pool allocation for " + std::to_string(meta.size())+ " signals and blocksize=" + std::to_string(blocksize)); - ret = pool_init(p, 1024, blocksize, &(memory_heap)); - if (ret) { - throw std::runtime_error("Villas_interface: pool_init failed for node " + _name + - " and node type " + std::string(type->name) + " with return value " + std::to_string(ret)); - } - - - // init VILLASnode based on config from above - IO->log_info("Villas_interface: node_init"); - ret = node_init(n, type); - if (ret) { - throw std::runtime_error("Villas_interface: node_init failed for node " + _name + - " and node type " + std::string(type->name) + " with return value " + std::to_string(ret)); - } - - //parse configuration of node - IO->log_info("Villas_interface: parsing node configuration"); - - n->name = strdup(_name.c_str()); - n->in.enabled = 1; - n->out.enabled = 1; - n->out.vectorize = 1; //only one sample at a time - n->in.vectorize = 1; - IO->log_info("Villas_interface: parsing config for " + std::string(type->name)); - if(std::string(type->name) == "mqtt") { - //configure the node for mqtt - - //set mqtt parameters - auto *m = (mqtt *) n->_vd; - - //set broker - m->host = strdup(_config->type_config.mqtt_conf->broker.c_str()) ; - - //set publish topic (if any) - if(!_config->type_config.mqtt_conf->publish.empty()){ - m->publish = strdup(_config->type_config.mqtt_conf->publish.c_str()); - } else{ - m->publish = nullptr; - } - //set subscribe topic (if any) - if(!_config->type_config.mqtt_conf->subscribe.empty()){ - m->subscribe = strdup(_config->type_config.mqtt_conf->subscribe.c_str()); - } else{ - m->subscribe = nullptr; - } - - m->username = nullptr; - m->password = nullptr; - m->port = _config->type_config.mqtt_conf->port; - m->retain = _config->type_config.mqtt_conf->retain; - m->keepalive = _config->type_config.mqtt_conf->keepalive; - m->qos = _config->type_config.mqtt_conf->qos; - //SSL config params - m->ssl.enabled = _config->type_config.mqtt_conf->ssl_enabled; - m->ssl.insecure = _config->type_config.mqtt_conf->ssl_insecure; - m->ssl.cert_reqs = _config->type_config.mqtt_conf->ssl_cert_reqs; - m->ssl.tls_version = strdup(_config->type_config.mqtt_conf->ssl_tls_version.c_str()); - m->ssl.cafile = strdup(_config->type_config.mqtt_conf->ssl_cafile.c_str()); - m->ssl.capath = strdup(_config->type_config.mqtt_conf->ssl_capath.c_str()); - m->ssl.certfile = strdup(_config->type_config.mqtt_conf->ssl_certfile.c_str()); - m->ssl.ciphers = strdup(_config->type_config.mqtt_conf->ssl_ciphers.c_str()); - m->ssl.keyfile = strdup(_config->type_config.mqtt_conf->ssl_keyfile.c_str()); - m->queue.queue.state = State::DESTROYED; - m->pool.state = State::DESTROYED; - - //lookup the format type for this mqtt node - m->formatter = villas::node::FormatFactory::make(_config->format_name); - } - else if (std::string(type->name) == "nanomsg") { - //configure the node for nanomsg - - // set nanomsg parameters - auto *m = (nanomsg *) n->_vd; - - ret = vlist_init(&m->out.endpoints); - if (ret) { - throw std::runtime_error("Villas_interface: vlist_init of out.endpoints failed for node " + _name + - " with return value " + std::to_string(ret)); - } - ret = vlist_init(&m->in.endpoints); - if (ret) { - throw std::runtime_error("Villas_interface: vlist_init of in.endpoints failed for node " + _name + - " with return value " + std::to_string(ret)); - } - - if(!_config->type_config.nanomsg_conf->in_endpoints.empty()) { - for(const auto& endpoint : _config->type_config.nanomsg_conf->in_endpoints){ - IO->log_info("PUSH IN ENDPOINT: " + endpoint); - vlist_push(&m->in.endpoints, &strdup(endpoint.c_str())[0]); - } - } - if(!_config->type_config.nanomsg_conf->out_endpoints.empty()) { - for(const auto& endpoint : _config->type_config.nanomsg_conf->out_endpoints){ - IO->log_info("PUSH OUT ENDPOINT: " + endpoint); - vlist_push(&m->out.endpoints, &strdup(endpoint.c_str())[0]); - } - } - m->formatter = villas::node::FormatFactory::make(_config->format_name); - } else { - //IO->log_info("Villas_interface: Error: node type " + std::string(type->name) + " not supported by DistAIX."); - throw std::runtime_error("Villas_interface: Error in node " + _name + ": node type " - + std::string(type->name) + " not supported."); - } - - - // generate list of signals for villas node based on meta information of message type - // configures behavior-specific input and output signals - // this does the job of "node_direction_parse(...)" - IO->log_info("Villas_interface: configure signals"); - for(auto & i : meta){ - SignalType sig_type; - - // map data type to VILLAS signal data types - if(i.type == VILLAS_DATA_TYPE_INT64){ - sig_type = SignalType::INTEGER; - } - else if(i.type == VILLAS_DATA_TYPE_DOUBLE){ - sig_type = SignalType::FLOAT; - } - else if(i.type == VILLAS_DATA_TYPE_BOOLEAN){ - sig_type = SignalType::BOOLEAN; - } - else if(i.type == VILLAS_DATA_TYPE_COMPLEX){ - sig_type = SignalType::COMPLEX; - } else { - sig_type = SignalType::INVALID; - } - - // create signals - struct signal * sig_in = signal_create(i.name.c_str(), i.unit.c_str(), sig_type); - struct signal * sig_out = signal_create(i.name.c_str(), i.unit.c_str(), sig_type); - - // save signals in Villas node signal lists - vlist_push(&(n->in.signals), sig_in); - vlist_push(&(n->out.signals), sig_out); - } - - - // set state to parsed to be able to continue with this node - n->state = State::PARSED; - // set in and out node directions to PARSED - n->in.state = State::PARSED; - n->out.state = State::PARSED; - - //check node - IO->log_info("Villas_interface: node_check"); - ret = node_check(n); - if (ret) { - throw std::runtime_error("Villas_interface: node_check failed for node " + _name + - " and node type " + std::string(type->name) + " with return value " + std::to_string(ret)); - } - - //prepare node - IO->log_info("Villas_interface: node_prepare"); - ret = node_prepare(n); - if (ret) { - throw std::runtime_error("Villas_interface: node_prepare failed for node " + _name + - " and node type " + std::string(type->name) + " with return value " + std::to_string(ret)); - } - } else{ - IO->log_info("This instance of Villas_interface is used without node"); - } - -#else - //Warn the user and throw exception - IO->log_info("ERROR: Your agent behavior is trying to instantiate a Villas_interface, but DistAIX is compiled without VILLASnode support.\n" - "This will very likely cause a simulation failure!\n" - "Pass option -villas to build_and_install.sh script to compile DistAIX with VILLASnode support"); - std::cerr << "ERROR: Your agent behavior is trying to instantiate a Villas_interface, but DistAIX is compiled without VILLASnode support." << std::endl; - std::cerr << "This will very likely cause a simulation failure!" << std::endl; - std::cerr << "Pass option -villas to build_and_install.sh script to compile DistAIX with VILLASnode support" << std::endl; - throw std::runtime_error("Villas_interface: Trying to create instance of VILLAS_interface, but DistAIX is compiled without libvillas. Check log files for more infos. I'm stopping here."); -#endif -} - - -/*! \brief Destructor of Villas_interface class - * - * */ -Villas_interface::~Villas_interface() { -#ifdef WITH_VILLAS - if(with_node) { - int ret; - ret = pool_destroy(p); - if (ret){ - IO->log_info("Villas_interface::Destructor pool_destroy failed for node " + std::string(n->name) + - " and node type " + std::string(type->name) + " with return value " + std::to_string(ret)); - } - } -#endif -} - - -/*! \brief Start a Villas_interface - * - * */ -int Villas_interface::start() { -#ifdef WITH_VILLAS - int ret =0; //for return values of villas functions - IO->log_info("Villas_interface::start: starting villas node " + std::string(n->name)); - if(with_node) { - ret = node_start(n); - if (ret) { - IO->log_info("Villas_interface::start: node_start failed for node " + std::string(n->name) + - " and node type " + std::string(type->name) + " ; ret="+std::to_string(ret)); - } - - } - else{ - IO->log_info("Villas_interface::start: Cannot start() villas node because this instance" - " of Villas_interface is used without node"); - } - - return ret; -#else - return -1; -#endif -} - - -/*! \brief Stop a Villas_interface - * - * */ -int Villas_interface::stop() { -#ifdef WITH_VILLAS - int ret =0; //for return values of villas functions - IO->log_info("Villas_interface::stop: stopping villas node " + std::string(n->name)); - if(with_node) { - ret = node_stop(n); - if (ret) { - IO->log_info("Villas_interface::stop: node_stop failed for node " + std::string(n->name) + - " and node type " + std::string(type->name)); - } - } - else{ - IO->log_info("Villas_interface::stop: Cannot stop() villas node because this instance" - " of Villas_interface is used without node"); - } - - return ret; -#else - return -1; -#endif -} - -/*! \brief Destroy a Villas_interface - * - * */ -int Villas_interface::destroy() { -#ifdef WITH_VILLAS - int ret =0; //for return values of villas functions - IO->log_info("Villas_interface::destroy: destroying villas node " + std::string(n->name)); - if(with_node) { - ret = node_destroy(n); - if (ret) { - IO->log_info("Villas_interface::destroy: node_destroy failed for node " + std::string(n->name) + - " and node type " + std::string(type->name)); - } - } - else{ - IO->log_info("Villas_interface::destroy: Cannot destroy() villas node because this instance " - "of Villas_interface is used without node" ); - } - return ret; -#else - return -1; -#endif -} - -/*! \brief Send a message via a Villas_interface - * - * */ -void Villas_interface::send_message(Villas_message &msg) { -#ifdef WITH_VILLAS - if(with_node) { - - //int ret = 0; - int allocated; - - struct sample * new_sample[n->out.vectorize]; - allocated = sample_alloc_many(p, new_sample, (int) n->out.vectorize); - - //fill sample - IO->log_info("Villas_interface::send_message: sending message of length: " + std::to_string(msg.length)); - new_sample[0]->length = msg.length; - new_sample[0]->sequence = number_of_sent_messages; - new_sample[0]->signals = &(n->out.signals); - for(unsigned int k = 0; k< msg.length; k++){ - if(meta[k].type == VILLAS_DATA_TYPE_INT64){ - //IO->log_info("Villas_interface::send_message: Filling int " + - // std::to_string(msg.data[k].i) + " at data[" + std::to_string(k) + "]" ); - new_sample[0]->data[k].i = msg.data[k].i; - } - else if(meta[k].type == VILLAS_DATA_TYPE_DOUBLE){ - //IO->log_info("Villas_interface::send_message: Filling double " + - // std::to_string(msg.data[k].f) + " at data[" + std::to_string(k) + "]" ); - new_sample[0]->data[k].f = msg.data[k].f; - } - else if(meta[k].type == VILLAS_DATA_TYPE_BOOLEAN){ - //IO->log_info("Villas_interface::send_message: Filling boolean " + - // std::to_string(msg.data[k].b) + " at data[" + std::to_string(k) + "]" ); - new_sample[0]->data[k].b = msg.data[k].b; - } - else if (meta[k].type == VILLAS_DATA_TYPE_COMPLEX){ - //IO->log_info("Villas_interface::send_message: Filling complex " + "[" + - // std::to_string(msg.data[k].c.real()) + "," + std::to_string(msg.data[k].c.imag()) + - // "]" + " at data[" + std::to_string(k) + "]" ); - new_sample[0]->data[k].z = msg.data[k].z; - } - } - - new_sample[0]->ts.origin.tv_sec = (long int) msg.time_sec; - double nano_sec = (msg.time_sec- (double) new_sample[0]->ts.origin.tv_sec) * 1000000000; - new_sample[0]->ts.origin.tv_nsec = (long int) (nano_sec); - - //set flags of sample - new_sample[0]->flags = 0; - new_sample[0]->flags |= (unsigned int) SampleFlags::HAS_DATA; - - // send sample - int release=allocated; - int sent = node_write(n, new_sample, n->out.vectorize); - IO->log_info("Villas_interface::send_message: node_write(...) completed, sent " + std::to_string(sent) + " samples"); - if (sent < 0) { - IO->log_info("Villas_interface::send_message: Failed to sent sample, reason=" + std::to_string(sent)); - } - number_of_sent_messages++; - sample_decref_many(new_sample, release); - sample_free_many(new_sample, (int) n->out.vectorize); - - - } - else{ - IO->log_info("Villas_interface::send_message: Cannot use send() for villas node" - " because this instance of Villas_interface is used without node"); - } - - //IO->log_info("Villas_interface::send_message: Finished!"); -#endif - -} - -void Villas_interface::allocate_and_receive(int number_of_messages, std::list &messages) { -#ifdef WITH_VILLAS - if(number_of_messages > 0) { - int allocated; - int release_number_of_messages = number_of_messages; - struct sample *new_sample[number_of_messages]; - allocated = sample_alloc_many(p, new_sample, number_of_messages); - int release = allocated; - - //IO->log_info("Allocated " + std::to_string(number_of_messages) + " samples"); - - // As nanomsg has no built-in queue, it is emulated by reading the socket for multiple times and - // seting the number_of_messages based on node_read()'s actual return values. - if (std::string(type->name) == "nanomsg"){ - struct sample *temp_sample[1]; // Temporary sample - int allocated_temp = sample_alloc_many(p, temp_sample, 1); - - int received = 0; - unsigned int index = 0; - - for (int i = 0; i < number_of_messages; ++i){ - - int recv = node_read(n, temp_sample, 1); - if (recv > 0){ - sample_copy(new_sample[index], temp_sample[0]); - received++; - index++; - // IO->log_info("temp_sample->data = "+ std::to_string(temp_sample[0]->data[0].z.real()) + "," - // + std::to_string(temp_sample[0]->data[0].z.imag()) + "]" + ","); - } - } - if (received > 0){ - number_of_messages = received; - IO->log_info("Villas_interface::receive_messages: node_read(...) completed, received " - + std::to_string(received) + " samples"); - } - else { // Skip error output as nanomsg polling is based on reading empty socket - number_of_messages = 0; - } - - // Free allocated memory for temporary sample - sample_decref_many(temp_sample, allocated_temp); - sample_free_many(temp_sample, 1); - } - else { - //receive sample - int recv = node_read(n, new_sample, number_of_messages); - IO->log_info("Villas_interface::receive_messages: node_read(...) completed, received " - + std::to_string(recv) + " samples"); - - if (recv < 0) { - IO->log_info("Villas_interface::receive_messages: Failed to receive samples," - " reason=" + std::to_string(recv)); - } - } - for (int x = 0; x < number_of_messages; x++) { - //print received samples - std::string output; - output += - "Villas_interface::receive_messages: Received the following sample of length " + - std::to_string(new_sample[x]->length) + ":\t"; - Villas_message new_msg; - for (unsigned int s = 0; s < new_sample[x]->length; s++) { - Data_element new_data; - if (meta[s].type == VILLAS_DATA_TYPE_INT64) { - new_data.i = new_sample[x]->data[s].i; - new_msg.add_element(new_data, VILLAS_DATA_TYPE_INT64); - output += std::to_string(new_sample[x]->data[s].i) + ","; - } - else if (meta[s].type == VILLAS_DATA_TYPE_DOUBLE) { - new_data.f = new_sample[x]->data[s].f; - new_msg.add_element(new_data, VILLAS_DATA_TYPE_DOUBLE); - output += std::to_string(new_sample[x]->data[s].f) + ","; - } - else if (meta[s].type == VILLAS_DATA_TYPE_BOOLEAN) { - new_data.b = new_sample[x]->data[s].b; - new_msg.add_element(new_data, VILLAS_DATA_TYPE_BOOLEAN); - output += std::to_string(new_sample[x]->data[s].b) + ","; - } - else if (meta[s].type == VILLAS_DATA_TYPE_COMPLEX) { - new_data.z = new_sample[x]->data[s].z; - new_msg.add_element(new_data, VILLAS_DATA_TYPE_COMPLEX); - output += "[" + std::to_string(new_sample[x]->data[s].z.real()) + "," - + std::to_string(new_sample[x]->data[s].z.imag()) + "]" + ","; - } - - } - IO->log_info(output); - - //set time - new_msg.time_sec = (double) new_sample[x]->ts.origin.tv_sec + - ((double) new_sample[x]->ts.origin.tv_nsec / 1000000000.0); - - messages.push_back(new_msg); - } - - //IO->log_info("sample_put_many"); - sample_decref_many(new_sample, release); - sample_free_many(new_sample, release_number_of_messages); - } -#endif -} - -/*! \brief Receive a message via a Villas_interface - * - * */ -void Villas_interface::receive_messages(std::list &messages) { -#ifdef WITH_VILLAS - if(with_node) { - - //receive all messages which are in incoming queue of villas node - messages.clear(); - - int number_of_messages; - // Check which villas node type is used and create corresponding struct - if(std::string(type->name) == "mqtt") { - auto * m = (struct mqtt*) n->_vd; - - //determine number of messages in the queue - unsigned long queue_tail = m->queue.queue.tail; - unsigned long queue_head = m->queue.queue.head; - number_of_messages = (int) (queue_tail - queue_head); - //IO->log_info("Villas_interface::receive_messages: " + std::to_string(number_of_messages) - // + " samples are in the queue"); - - // call allocate and receive for number_of_messages samples - if(number_of_messages > 0){ - allocate_and_receive(number_of_messages, messages); - } - } - else if(std::string(type->name) == "nanomsg") { - allocate_and_receive(1000, messages); // 128kB Memory / 8 Byte per message = 16000 messages - } - } - else { - IO->log_info("Villas_interface::receive_messages: Cannot use receive() for villas node" - " because this instance of Villas_interface is used without node"); - } - - - //IO->log_info("Villas_interface::receive_messages: Finished receiving of " - // + std::to_string(messages.size()) + " messages."); -#endif -} - -/*! \brief Method to start a node type; should only be called once per process - * - * */ -int Villas_interface::start_node_type() { -#ifdef WITH_VILLAS - int ret; - - //init memory subsystem in each process - ret = memory_init(0); - if(ret){ - IO->log_info("Villas_interface::start_node_type: memory_init failed for type " + std::string(type->name)); - } - - //start node type - IO->log_info("Villas_interface::start_node_type: Starting villas node type " + std::string(type->name)); - ret = node_type_start(type, nullptr); - if(ret){ - IO->log_info("Villas_interface::start_node_type: node_type_start failed for type " + std::string(type->name)); - } - - return ret; -#else - return -1; -#endif -} - - -/*! \brief Method to stop a node type; should only be called once per process - * - * */ -int Villas_interface::stop_node_type() { -#ifdef WITH_VILLAS - int ret; - //stop node type - IO->log_info("Villas_interface::stop_node_type: Stopping villas node type " + std::string(type->name)); - ret = node_type_stop(type); - if(ret){ - IO->log_info("Villas_interface::stop_node_type: node_type_stop failed for type " + std::string(type->name)); - } - - return ret; -#else - return -1; -#endif -} diff --git a/src/villas_interface/villas_message.cpp b/src/villas_interface/villas_message.cpp deleted file mode 100644 index f684db97b49e0772f4c1a53cabad3ae5a36073b6..0000000000000000000000000000000000000000 --- a/src/villas_interface/villas_message.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/** - * This file is part of DistAIX - * - * 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 . - *********************************************************************************/ - -#include "villas_interface/villas_message.h" - -Villas_message::Villas_message() { - length =0; - data.clear(); - time_sec = 0.0; -} - -void Villas_message::add_element(Data_element _d, int _type) { - - //Add data element and corresponding meta info - data.push_back(_d); - length++; -}