Skip to content

Commit

Permalink
Merge pull request #3 from openMSL/server-client-config
Browse files Browse the repository at this point in the history
Enable use of client/server config with ZeroMQ
  • Loading branch information
ClemensLinnhoff authored Oct 10, 2023
2 parents 28cdee8 + e3c72a3 commit b6f5f76
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/fmu_checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
key: ${{ runner.os }}-model-fmu

- name: Install FMPy
run: python -m pip install fmpy[complete]
run: python -m pip install fmpy==0.3.16

- name: Run FMPy Validate
working-directory: /tmp/model_fmu
Expand Down
34 changes: 17 additions & 17 deletions .github/workflows/srmd-validator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@ jobs:
name: SRMD Validator
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Checkout
uses: actions/checkout@master

- name: Get Sensor Model Testing
run: git clone https://github.com/openMSL/sl-1-5-sensor-model-testing.git
- name: Get SRMD Validator
run: git clone https://github.com/openMSL/sl-5-1-srmd-validator.git

- name: Init Submodules
working-directory: sl-1-5-sensor-model-testing
run: git submodule update --init --recursive
- name: Init Submodules
working-directory: sl-5-1-srmd-validator
run: git submodule update --init --recursive

- name: Install Dependencies
run: pip3 install xmlschema
- name: Install Dependencies
run: pip3 install xmlschema

- name: Validate SRMD
working-directory: sl-1-5-sensor-model-testing/src/srmd-validator
run: python3 srmd-validator.py
- name: Validate SRMD
working-directory: sl-5-1-srmd-validator
run: python3 srmd-validator.py

- name: Commit ID
working-directory: sl-1-5-sensor-model-testing
run: |
echo "Commit ID: "
echo $(git rev-parse --short HEAD)
- name: Commit ID
working-directory: sl-5-1-srmd-validator
run: |
echo "Commit ID: "
echo $(git rev-parse --short HEAD)
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ The following FMI parameters can be set.
Either `sender` or `receiver` have to be set to _true_.
Otherwise, the FMU will return with an error.

| Type | Parameter | Default | Description |
|---------|------------|-------------|--------------------------------------------|
| Boolean | `sender` | _true_ | Set if Proxy shall send data via TCP/IP |
| Boolean | `receiver` | _false_ | Set if Proxy shall receive data via TCP/IP |
| String | `ip` | _127.0.0.1_ | IP address of TCP connection |
| String | `port` | _3456_ | Port of TCP connection |
| Type | Parameter | Default | Description |
|---------|------------|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Boolean | `sender` | _true_ | Set if Proxy shall send data via TCP/IP |
| Boolean | `receiver` | _false_ | Set if Proxy shall receive data via TCP/IP |
| Boolean | `pushpull` | _false_ | If true, use [Push/Pull](https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pushpull.html) ZeroMQ configuration, if false, use [Client/Server](https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/client_server.html) config. |
| String | `ip` | _127.0.0.1_ | IP address of TCP connection |
| String | `port` | _3456_ | Port of TCP connection |

## Interface

Expand Down
39 changes: 33 additions & 6 deletions src/OSMP.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//
// Copyright 2016 -- 2018 PMSF IT Consulting Pierre R. Mai
// Copyright 2023 BMW AG
// Copyright 2023 Persival GmbH
// SPDX-License-Identifier: MPL-2.0
//

Expand Down Expand Up @@ -132,11 +133,10 @@ fmi2Status OSMP::DoInit()
// Set default values
SetFmiSender(1);
SetFmiReceiver(0);
SetFmiPushPull(1);
SetFmiIp("127.0.0.1");
SetFmiPort("3456");

// todo: set default values

return fmi2OK;
}

Expand All @@ -156,22 +156,36 @@ fmi2Status OSMP::DoExitInitializationMode()
string address = "tcp://" + FmiIp() + ":" + FmiPort();
std::cout << address << std::endl;
const char* protocol = address.c_str();

if (FmiSender() != 0)
{
socket_ = zmq::socket_t(context_, ZMQ_PUSH);
if (FmiPushPull() != 0) // Push/Pull configuration
{
socket_ = zmq::socket_t(context_, ZMQ_PUSH);
}
else // Server/Client configuration
{
socket_ = zmq::socket_t(context_, ZMQ_REP);
}
const int wait_time_ms = 5000;
zmq_setsockopt(socket_, ZMQ_SNDTIMEO, &wait_time_ms, sizeof(wait_time_ms));
socket_.bind(protocol);
std::cout << "push" << std::endl;
}
else
{
socket_ = zmq::socket_t(context_, ZMQ_PULL);
if (FmiPushPull() != 0) // Push/Pull configuration
{
socket_ = zmq::socket_t(context_, ZMQ_PULL);
}
else // Server/Client configuration
{
socket_ = zmq::socket_t(context_, ZMQ_REQ);
}
const int wait_time_ms = 5000;
zmq_setsockopt(socket_, ZMQ_RCVTIMEO, &wait_time_ms, sizeof(wait_time_ms));
socket_.connect(protocol);
std::cout << "pull" << std::endl;
}

return fmi2OK;
}

Expand All @@ -193,6 +207,11 @@ fmi2Status OSMP::DoCalc(fmi2Real current_communication_point, fmi2Real communica

if (FmiSender() != 0)
{
if (FmiPushPull() == 0) // Server/Client configuration
{
zmq::message_t request_message;
socket_.recv(request_message, zmq::recv_flags::none);
}
zmq::message_t send_message(buffer, buffer_size, nullptr);
auto success = socket_.send(send_message, zmq::send_flags::none);
if (success.has_value())
Expand All @@ -207,6 +226,13 @@ fmi2Status OSMP::DoCalc(fmi2Real current_communication_point, fmi2Real communica
}
else if (FmiReceiver() != 0)
{
if (FmiPushPull() == 0) // Server/Client configuration
{
std::stringstream s;
s << "ready";
zmq::message_t send_message(s.str().data(), s.str().size());
socket_.send(send_message, zmq::send_flags::none);
}
zmq::message_t rec_message;
auto success = socket_.recv(rec_message, zmq::recv_flags::none);
if (success.has_value())
Expand All @@ -224,6 +250,7 @@ fmi2Status OSMP::DoCalc(fmi2Real current_communication_point, fmi2Real communica
NormalLog("OSMP", "Either sender or receiver has to be set to true.");
output_status = fmi2Error;
}

return output_status;
}

Expand Down
64 changes: 52 additions & 12 deletions src/OSMP.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//
// Copyright 2016 -- 2018 PMSF IT Consulting Pierre R. Mai
// Copyright 2023 BMW AG
// Copyright 2023 Persival GmbH
// SPDX-License-Identifier: MPL-2.0
//

Expand Down Expand Up @@ -42,7 +43,8 @@
#define FMI_BOOLEAN_VALID_IDX 0
#define FMI_BOOLEAN_SENDER_IDX 1
#define FMI_BOOLEAN_RECEIVER_IDX 2
#define FMI_BOOLEAN_LAST_IDX FMI_BOOLEAN_RECEIVER_IDX
#define FMI_BOOLEAN_PUSHPULL_IDX 3
#define FMI_BOOLEAN_LAST_IDX FMI_BOOLEAN_PUSHPULL_IDX
#define FMI_BOOLEAN_VARS (FMI_BOOLEAN_LAST_IDX + 1)

/* Integer Variables */
Expand Down Expand Up @@ -177,7 +179,7 @@ class OSMP
}
#endif
#ifdef PUBLIC_LOGGING
if (logging_on_ && (logging_categories_.count(category) != 0u))
if (logging_on_ && (logging_categories_.count(category) != 0U))
{
functions_.logger(functions_.componentEnvironment, instance_name_.c_str(), fmi2OK, category, buffer);
}
Expand Down Expand Up @@ -227,14 +229,52 @@ class OSMP
zmq::socket_t socket_;

/* Simple Accessors */
fmi2Boolean FmiValid() { return boolean_vars_[FMI_BOOLEAN_VALID_IDX]; }
void SetFmiValid(fmi2Boolean value) { boolean_vars_[FMI_BOOLEAN_VALID_IDX] = value; }
fmi2Boolean FmiReceiver() { return boolean_vars_[FMI_BOOLEAN_RECEIVER_IDX]; }
void SetFmiReceiver(fmi2Boolean value) { boolean_vars_[FMI_BOOLEAN_RECEIVER_IDX] = value; }
fmi2Boolean FmiSender() { return boolean_vars_[FMI_BOOLEAN_SENDER_IDX]; }
void SetFmiSender(fmi2Boolean value) { boolean_vars_[FMI_BOOLEAN_SENDER_IDX] = value; }
string FmiIp() { return string_vars_[FMI_STRING_IP_IDX]; }
void SetFmiIp(fmi2String value) { string_vars_[FMI_STRING_IP_IDX] = value; }
string FmiPort() { return string_vars_[FMI_STRING_PORT_IDX]; }
void SetFmiPort(fmi2String value) { string_vars_[FMI_STRING_PORT_IDX] = value; }
fmi2Boolean FmiValid()
{
return boolean_vars_[FMI_BOOLEAN_VALID_IDX];
}
void SetFmiValid(fmi2Boolean value)
{
boolean_vars_[FMI_BOOLEAN_VALID_IDX] = value;
}
fmi2Boolean FmiReceiver()
{
return boolean_vars_[FMI_BOOLEAN_RECEIVER_IDX];
}
void SetFmiReceiver(fmi2Boolean value)
{
boolean_vars_[FMI_BOOLEAN_RECEIVER_IDX] = value;
}
fmi2Boolean FmiSender()
{
return boolean_vars_[FMI_BOOLEAN_SENDER_IDX];
}
void SetFmiSender(fmi2Boolean value)
{
boolean_vars_[FMI_BOOLEAN_SENDER_IDX] = value;
}
fmi2Boolean FmiPushPull()
{
return boolean_vars_[FMI_BOOLEAN_PUSHPULL_IDX];
}
void SetFmiPushPull(fmi2Boolean value)
{
boolean_vars_[FMI_BOOLEAN_PUSHPULL_IDX] = value;
}
string FmiIp()
{
return string_vars_[FMI_STRING_IP_IDX];
}
void SetFmiIp(fmi2String value)
{
string_vars_[FMI_STRING_IP_IDX] = value;
}
string FmiPort()
{
return string_vars_[FMI_STRING_PORT_IDX];
}
void SetFmiPort(fmi2String value)
{
string_vars_[FMI_STRING_PORT_IDX] = value;
}
};
3 changes: 3 additions & 0 deletions src/modelDescription.in.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
<ScalarVariable name="receiver" valueReference="2" causality="parameter" variability="fixed" initial="exact">
<Boolean start="false"/>
</ScalarVariable>
<ScalarVariable name="pushpull" valueReference="3" causality="parameter" variability="fixed" initial="exact">
<Boolean start="true"/>
</ScalarVariable>
<ScalarVariable name="ip" valueReference="0" causality="parameter" variability="fixed" initial="exact">
<String start="127.0.0.1"/>
</ScalarVariable>
Expand Down

1 comment on commit b6f5f76

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-tidy reports: 5 concern(s)
  • src/OSMP.cpp

    /src/OSMP.cpp:50:16: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 'private_log_file' is non-const and globally accessible, consider making it const

    ofstream OSMP::private_log_file;
                   ^
  • src/OSMP.h

    /src/OSMP.h:134:21: warning: [cppcoreguidelines-avoid-non-const-global-variables]

    variable 'private_log_file' is non-const and globally accessible, consider making it const

        static ofstream private_log_file;
                        ^

    /src/OSMP.h:134:21: warning: [readability-identifier-naming]

    invalid case style for class member 'private_log_file'

        static ofstream private_log_file;
                        ^~~~~~~~~~~~~~~~
                        g_private_log_file

    /src/OSMP.h:164:21: warning: [cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers]

    1024 is a magic number; consider replacing it with a named constant

            char buffer[1024];
                        ^

    /src/OSMP.h:168:27: warning: [cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers]

    1024 is a magic number; consider replacing it with a named constant

            vsnprintf(buffer, 1024, format, arg);
                              ^

Have any feedback or feature suggestions? Share it here.

Please sign in to comment.