Skip to content

Commit 51013eb

Browse files
committed
mqtt: ref-dev-mqtt-fb-pub example
1 parent 44b2745 commit 51013eb

4 files changed

Lines changed: 169 additions & 0 deletions

File tree

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ if (OPENDAQ_MQTT_ENABLE_EXAMPLE_APPS)
55
add_subdirectory(ref-dev-mqtt-sub)
66
add_subdirectory(ref-dev-mqtt-raw-sub)
77
add_subdirectory(custom-mqtt-sub)
8+
add_subdirectory(ref-dev-mqtt-fb-pub)
89
endif()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
set(EXAMPLE_PROJECT_NAME "ref-dev-mqtt-fb-pub")
4+
5+
project(${EXAMPLE_PROJECT_NAME} LANGUAGES CXX)
6+
7+
set(CMAKE_CXX_STANDARD 17)
8+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
9+
10+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
11+
12+
add_subdirectory(src)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
add_compile_definitions(MODULE_PATH="${OPENDAQ_MODULES_DIR}")
4+
add_compile_definitions(APP_NAME="${EXAMPLE_PROJECT_NAME}")
5+
6+
add_executable(${EXAMPLE_PROJECT_NAME} ref-dev-mqtt-fb-pub.cpp)
7+
add_dependencies(${EXAMPLE_PROJECT_NAME} daq::ref_device_module)
8+
target_link_libraries(${EXAMPLE_PROJECT_NAME} PRIVATE daq::opendaq)
9+
target_include_directories(${EXAMPLE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../)
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "../../InputArgs.h"
2+
#include <opendaq/opendaq.h>
3+
4+
#include <iostream>
5+
6+
using namespace daq;
7+
8+
enum class Mode {
9+
SINGLE = 0,
10+
SINGLE_PACK,
11+
MULTI_SINGLE,
12+
MULTI_SHARED,
13+
_COUNT
14+
};
15+
16+
struct ConfigStruct {
17+
std::string brokerAddress;
18+
Mode mode;
19+
bool exit = true;
20+
int error = 0;
21+
};
22+
23+
ConfigStruct StartUp(int argc, char* argv[])
24+
{
25+
ConfigStruct config;
26+
InputArgs args;
27+
args.addArg("--help", "Show help message");
28+
args.addArg("--address", "MQTT broker address", true);
29+
args.addArg("--mode", "publisher FB mode", true);
30+
args.setUsageHelp(APP_NAME " [options]\n"
31+
"Available modes:\n"
32+
" 0 - Single\n"
33+
" 1 - Single with packing\n"
34+
" 2 - Multi Single\n"
35+
" 3 - Multi Shared");
36+
args.parse(argc, argv);
37+
38+
if (args.hasArg("--help") || args.hasUnknownArgs())
39+
{
40+
args.printHelp();
41+
config.error = 0;
42+
return config;
43+
}
44+
45+
config.brokerAddress = args.getArgValue("--address", "127.0.0.1");
46+
config.exit = false;
47+
int mode = std::stoi(args.getArgValue("--mode", "0"));
48+
if (mode < 0 || mode >= static_cast<int>(Mode::_COUNT))
49+
{
50+
std::cout << "Invalid mode value. Allowed values are from 0 to " << (static_cast<int>(Mode::_COUNT) - 1) << "." << std::endl;
51+
args.printHelp();
52+
config.error = -1;
53+
config.exit = true;
54+
return config;
55+
}
56+
config.mode = static_cast<Mode>(mode);
57+
return config;
58+
}
59+
60+
int main(int argc, char* argv[])
61+
{
62+
// Parse input arguments
63+
auto appConfig = StartUp(argc, argv);
64+
if (appConfig.exit)
65+
{
66+
return appConfig.error;
67+
}
68+
69+
const InstancePtr instance = InstanceBuilder().addModulePath(MODULE_PATH).setRootDevice("daqref://device0").build();
70+
auto refDevice = instance.getRootDevice();
71+
refDevice.setPropertyValue("NumberOfChannels", 4);
72+
refDevice.setPropertyValue("GlobalSampleRate", 100);
73+
74+
// Configure channels
75+
const auto channels = refDevice.getChannelsRecursive();
76+
channels[0].setPropertyValue("UseGlobalSampleRate", appConfig.mode == Mode::MULTI_SHARED);
77+
channels[0].setPropertyValue("SampleRate", 10);
78+
channels[0].setPropertyValue("Frequency", 1);
79+
channels[0].setPropertyValue("Waveform", 1);
80+
channels[1].setPropertyValue("UseGlobalSampleRate", appConfig.mode == Mode::MULTI_SHARED);
81+
channels[1].setPropertyValue("SampleRate", 20);
82+
channels[1].setPropertyValue("Frequency", 1);
83+
channels[1].setPropertyValue("Waveform", 3);
84+
channels[2].setPropertyValue("UseGlobalSampleRate", appConfig.mode == Mode::MULTI_SHARED);
85+
channels[2].setPropertyValue("SampleRate", 50);
86+
channels[2].setPropertyValue("Frequency", 4);
87+
channels[3].setPropertyValue("UseGlobalSampleRate", appConfig.mode == Mode::MULTI_SHARED);
88+
channels[3].setPropertyValue("SampleRate", 100);
89+
channels[3].setPropertyValue("Frequency", 20);
90+
91+
// Create and configure MQTT server
92+
auto brokerDevice = instance.addDevice("daq.mqtt://" + appConfig.brokerAddress);
93+
auto availableDeviceNodes = brokerDevice.getAvailableFunctionBlockTypes();
94+
const std::string fbName = "@publisherMqttFb";
95+
std::cout << "Try to add the " << fbName << std::endl;
96+
97+
auto config = availableDeviceNodes.get(fbName).createDefaultConfig();
98+
config.setPropertyValue("MqttQoS", 1);
99+
config.setPropertyValue("ReaderPeriod", 20);
100+
config.setPropertyValue("UseSignalNames", True);
101+
switch (appConfig.mode) {
102+
case Mode::SINGLE:
103+
config.setPropertyValue("SharedTimestamp", False);
104+
config.setPropertyValue("TopicMode", 0);
105+
config.setPropertyValue("GroupValues", False);
106+
break;
107+
case Mode::SINGLE_PACK:
108+
config.setPropertyValue("SharedTimestamp", False);
109+
config.setPropertyValue("TopicMode", 0);
110+
config.setPropertyValue("GroupValues", True);
111+
config.setPropertyValue("GroupValuesPackSize", 3);
112+
break;
113+
case Mode::MULTI_SINGLE:
114+
config.setPropertyValue("SharedTimestamp", False);
115+
config.setPropertyValue("TopicMode", 1);
116+
config.setPropertyValue("GroupValues", False);
117+
break;
118+
case Mode::MULTI_SHARED:
119+
config.setPropertyValue("SharedTimestamp", True);
120+
config.setPropertyValue("TopicMode", 1);
121+
config.setPropertyValue("GroupValues", False);
122+
break;
123+
default:
124+
break;
125+
}
126+
127+
128+
// Add the publisher function block to the broker device
129+
daq::FunctionBlockPtr fb = brokerDevice.addFunctionBlock(fbName, config);
130+
const auto signals = refDevice.getSignals(search::Recursive(search::Any()));
131+
for (const auto& s : signals)
132+
{
133+
if (s.getDomainSignal().assigned())
134+
{
135+
auto ports = fb.getInputPorts();
136+
ports[ports.getCount() - 1].connect(s);
137+
}
138+
}
139+
140+
auto status = fb.getStatusContainer().getStatus("ComponentStatus");
141+
const auto statusStr = status.getValue();
142+
if (statusStr != "Ok")
143+
return -1;
144+
std::cout << "Press \"enter\" to exit the application..." << std::endl;
145+
std::cin.get();
146+
return 0;
147+
}

0 commit comments

Comments
 (0)