stinger-ipc 0.0.10__py3-none-any.whl → 0.0.26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stinger_ipc-0.0.10.dist-info → stinger_ipc-0.0.26.dist-info}/METADATA +3 -2
- {stinger_ipc-0.0.10.dist-info → stinger_ipc-0.0.26.dist-info}/RECORD +35 -29
- stingeripc/asyncapi.py +3 -0
- stingeripc/components.py +61 -10
- stingeripc/schema/schema.yaml +240 -0
- stingeripc/templates/cpp/examples/client_main.cpp.jinja2 +18 -0
- stingeripc/templates/cpp/include/broker.hpp.jinja2 +18 -10
- stingeripc/templates/cpp/include/client.hpp.jinja2 +80 -11
- stingeripc/templates/cpp/include/ibrokerconnection.hpp.jinja2 +24 -4
- stingeripc/templates/cpp/include/property_structs.hpp.jinja2 +40 -2
- stingeripc/templates/cpp/include/server.hpp.jinja2 +5 -1
- stingeripc/templates/cpp/include/structs.hpp.jinja2 +2 -0
- stingeripc/templates/cpp/partials/args.jinja2 +11 -0
- stingeripc/templates/cpp/partials/deserialize.jinja2 +42 -0
- stingeripc/templates/cpp/partials/serialize.jinja2 +18 -0
- stingeripc/templates/cpp/src/broker.cpp.jinja2 +46 -24
- stingeripc/templates/cpp/src/client.cpp.jinja2 +111 -38
- stingeripc/templates/cpp/src/property_structs.cpp.jinja2 +25 -0
- stingeripc/templates/cpp/src/server.cpp.jinja2 +17 -25
- stingeripc/templates/cpp/src/structs.cpp.jinja2 +13 -0
- stingeripc/templates/html/app.js.jinja2 +130 -29
- stingeripc/templates/html/index.html.jinja2 +96 -8
- stingeripc/templates/html/styles.css.jinja2 +135 -0
- stingeripc/templates/markdown/index.md.jinja2 +151 -10
- stingeripc/templates/python/server.py.jinja2 +138 -18
- stingeripc/templates/rust/client/src/lib.rs.jinja2 +24 -5
- stingeripc/templates/rust/server/examples/server.rs.jinja2 +59 -23
- stingeripc/templates/rust/server/src/lib.rs.jinja2 +72 -51
- stingeripc/tools/cli.py +33 -7
- stingeripc/tools/cpp_generator.py +90 -0
- stingeripc/tools/rust_generator.py +1 -1
- stingeripc/templates/rust/payloads/src/handler.rs.jinja2 +0 -0
- {stinger_ipc-0.0.10.dist-info → stinger_ipc-0.0.26.dist-info}/WHEEL +0 -0
- {stinger_ipc-0.0.10.dist-info → stinger_ipc-0.0.26.dist-info}/entry_points.txt +0 -0
- {stinger_ipc-0.0.10.dist-info → stinger_ipc-0.0.26.dist-info}/licenses/LICENSE +0 -0
- {stinger_ipc-0.0.10.dist-info → stinger_ipc-0.0.26.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,7 @@
|
|
1
|
+
{% import "partials/deserialize.jinja2" as deser %}
|
2
|
+
{% import "partials/serialize.jinja2" as ser %}
|
3
|
+
{% import "partials/args.jinja2" as ar %}
|
4
|
+
{%macro prop_value_type(prop) -%}{%if prop.arg_list|length > 1%}struct {%endif%}{{prop.name | UpperCamelCase}}Property{%endmacro%}
|
1
5
|
|
2
6
|
#include <vector>
|
3
7
|
#include <iostream>
|
@@ -16,20 +20,22 @@
|
|
16
20
|
#include "{{stinger.cpp.enum_header_file}}"
|
17
21
|
#include "ibrokerconnection.hpp"
|
18
22
|
|
19
|
-
|
20
23
|
constexpr const char {{stinger.cpp.client_class_name}}::NAME[];
|
21
24
|
constexpr const char {{stinger.cpp.client_class_name}}::INTERFACE_VERSION[];
|
22
25
|
|
23
26
|
{{stinger.cpp.client_class_name}}::{{stinger.cpp.client_class_name}}(std::shared_ptr<IBrokerConnection> broker) : _broker(broker)
|
24
27
|
{
|
25
|
-
_broker->AddMessageCallback([this](
|
28
|
+
_broker->AddMessageCallback([this](
|
29
|
+
const std::string& topic,
|
30
|
+
const std::string& payload,
|
31
|
+
const MqttProperties& mqttProps)
|
26
32
|
{
|
27
|
-
_receiveMessage(topic, payload,
|
33
|
+
_receiveMessage(topic, payload, mqttProps);
|
28
34
|
});
|
29
35
|
|
30
36
|
{%-for sig_name, sig in stinger.signals.items() %}
|
31
|
-
_broker->Subscribe("{{sig.topic}}",
|
32
|
-
{
|
37
|
+
_{{sig_name | lowerCamelCase}}SignalSubscriptionId = _broker->Subscribe("{{sig.topic}}", 2);
|
38
|
+
{%-endfor%}
|
33
39
|
{%-for method_name, method in stinger.methods.items() %}
|
34
40
|
{ // Restrict scope
|
35
41
|
std::stringstream responseTopicStringStream;
|
@@ -37,21 +43,24 @@ constexpr const char {{stinger.cpp.client_class_name}}::INTERFACE_VERSION[];
|
|
37
43
|
_broker->Subscribe(responseTopicStringStream.str(), 2);
|
38
44
|
}
|
39
45
|
{%-endfor%}
|
46
|
+
|
47
|
+
{%-for prop_name, prop in stinger.properties.items() %}
|
48
|
+
_{{prop_name | lowerCamelCase}}PropertySubscriptionId = _broker->Subscribe("{{prop.value_topic}}", 1);
|
49
|
+
{%-endfor%}
|
40
50
|
}
|
41
51
|
|
42
52
|
void {{stinger.cpp.client_class_name}}::_receiveMessage(
|
43
53
|
const std::string& topic,
|
44
54
|
const std::string& payload,
|
45
|
-
const
|
46
|
-
const boost::optional<MethodResultCode> optResultCode)
|
55
|
+
const MqttProperties& mqttProps)
|
47
56
|
{
|
48
57
|
{%-for sig_name, sig in stinger.signals.items() %}
|
49
|
-
if (_broker->TopicMatchesSubscription(topic, "{{sig.topic}}"))
|
58
|
+
if ((mqttProps.subscriptionId && (*mqttProps.subscriptionId == _{{sig_name | lowerCamelCase}}SignalSubscriptionId)) || _broker->TopicMatchesSubscription(topic, "{{sig.topic}}"))
|
50
59
|
{
|
51
60
|
//Log("Handling {{sig_name}} signal");
|
52
61
|
rapidjson::Document doc;
|
53
62
|
try {
|
54
|
-
if (_{{sig_name | camelCase}}
|
63
|
+
if (_{{sig_name | camelCase}}SignalCallbacks.size() > 0)
|
55
64
|
{
|
56
65
|
rapidjson::ParseResult ok = doc.Parse(payload.c_str());
|
57
66
|
if (!ok)
|
@@ -82,9 +91,11 @@ void {{stinger.cpp.client_class_name}}::_receiveMessage(
|
|
82
91
|
{%endif%}
|
83
92
|
}
|
84
93
|
}
|
85
|
-
{%endfor%}
|
86
|
-
|
87
|
-
|
94
|
+
{%endfor%}{# for signal args #}
|
95
|
+
for (const auto& cb : _{{sig_name | lowerCamelCase}}SignalCallbacks)
|
96
|
+
{
|
97
|
+
cb({%for arg in sig.arg_list%}temp{{arg.name}}{%if not loop.last%}, {%endif%}{%endfor%});
|
98
|
+
}
|
88
99
|
}
|
89
100
|
}
|
90
101
|
catch (const boost::bad_lexical_cast&)
|
@@ -94,21 +105,29 @@ void {{stinger.cpp.client_class_name}}::_receiveMessage(
|
|
94
105
|
// TODO: Log this failure
|
95
106
|
}
|
96
107
|
}
|
97
|
-
{%-endfor%}
|
108
|
+
{%-endfor%}{# for signals #}
|
109
|
+
|
98
110
|
{%-for method_name, method in stinger.methods.items() %}
|
99
|
-
{%if not loop.first%}else {%endif%}if (_broker->TopicMatchesSubscription(topic, "{{method.response_topic('+')}}") &&
|
111
|
+
{%if not loop.first%}else {%endif%}if (_broker->TopicMatchesSubscription(topic, "{{method.response_topic('+')}}") && mqttProps.correlationId)
|
100
112
|
{
|
101
113
|
std::cout << "Matched topic for {{method_name}} response" << std::endl;
|
102
|
-
_handle{{method_name|UpperCamelCase}}Response(topic, payload, *
|
114
|
+
_handle{{method_name|UpperCamelCase}}Response(topic, payload, *mqttProps.correlationId);
|
103
115
|
}
|
104
|
-
{%-endfor%}
|
116
|
+
{%-endfor%}{# for methods #}
|
117
|
+
|
118
|
+
{%-for prop_name, prop in stinger.properties.items() %}
|
119
|
+
{%if not loop.first%}else {%endif%}if ((mqttProps.subscriptionId && (*mqttProps.subscriptionId == _{{prop_name | lowerCamelCase}}PropertySubscriptionId)) || topic == "{{prop.value_topic}}")
|
120
|
+
{
|
121
|
+
_receive{{prop_name | UpperCamelCase}}PropertyUpdate(topic, payload, mqttProps.propertyVersion);
|
122
|
+
}
|
123
|
+
{%-endfor%}{# for properties #}
|
105
124
|
}
|
106
125
|
|
107
126
|
|
108
127
|
{%-for sig_name, sig in stinger.signals.items() %}
|
109
128
|
void {{stinger.cpp.client_class_name}}::register{{sig_name | UpperCamelCase}}Callback(const std::function<void({%for arg in sig.arg_list%}{{arg.cpp_type}}{%if not loop.last%}, {%endif%}{%endfor%})>& cb)
|
110
129
|
{
|
111
|
-
_{{sig_name |
|
130
|
+
_{{sig_name | lowerCamelCase}}SignalCallbacks.push_back(cb);
|
112
131
|
}
|
113
132
|
{%-endfor%}
|
114
133
|
|
@@ -122,31 +141,19 @@ boost::future<{{method.return_value_cpp_class}}> {{stinger.cpp.client_class_name
|
|
122
141
|
rapidjson::Document doc;
|
123
142
|
doc.SetObject();
|
124
143
|
|
125
|
-
{%-macro addToDoc(arg)%}
|
126
|
-
{%-if arg.arg_type.name.lower() == 'primitive'%}
|
127
|
-
{%-if arg.optional %}if ({{arg.name}}) {%endif-%}
|
128
|
-
{%-if arg.type.name.lower() == 'string'%}
|
129
|
-
{ // restrict scope
|
130
|
-
rapidjson::Value tempStringValue;
|
131
|
-
tempStringValue.SetString({{arg.name}}{%-if arg.optional %}->{%else%}.{%endif-%}c_str(), {{arg.name}}.size(), doc.GetAllocator());
|
132
|
-
doc.AddMember("{{arg.name}}", tempStringValue, doc.GetAllocator());
|
133
|
-
}
|
134
|
-
{%-else%}
|
135
|
-
doc.AddMember("{{arg.name}}", {%-if arg.optional %}*{%endif-%}{{arg.name}}, doc.GetAllocator());
|
136
|
-
{%-endif%}
|
137
|
-
{%elif arg.arg_type.name.lower() == 'enum'%}
|
138
|
-
doc.AddMember("{{arg.name}}", static_cast<int>({{arg.name}}), doc.GetAllocator());
|
139
|
-
{%-endif-%}
|
140
|
-
{%endmacro%}
|
141
144
|
{%for arg in method.arg_list%}
|
142
|
-
{{
|
145
|
+
{{ser.addToValue('doc', arg, 'doc.GetAllocator()') | indent(4)}}
|
143
146
|
{%endfor%}
|
144
147
|
rapidjson::StringBuffer buf;
|
145
148
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
|
146
149
|
doc.Accept(writer);
|
147
150
|
std::stringstream responseTopicStringStream;
|
148
151
|
responseTopicStringStream << boost::format("{{method.response_topic('%1%')}}") % _broker->GetClientId();
|
149
|
-
|
152
|
+
MqttProperties mqttProps;
|
153
|
+
mqttProps.correlationId = correlationIdStr;
|
154
|
+
mqttProps.responseTopic = responseTopicStringStream.str();
|
155
|
+
mqttProps.resultCode = MethodResultCode::SUCCESS;
|
156
|
+
_broker->Publish("{{method.topic}}", buf.GetString(), 2, false, mqttProps);
|
150
157
|
|
151
158
|
return _pending{{method_name|UpperCamelCase}}MethodCalls[correlationId].get_future();
|
152
159
|
}
|
@@ -157,6 +164,7 @@ void {{stinger.cpp.client_class_name}}::_handle{{method_name|UpperCamelCase}}Res
|
|
157
164
|
const std::string &correlationId)
|
158
165
|
{
|
159
166
|
std::cout << "In response handler for " << topic << " with correlationId=" << correlationId << std::endl;
|
167
|
+
{%if method.return_value_type is not false%}
|
160
168
|
rapidjson::Document doc;
|
161
169
|
rapidjson::ParseResult ok = doc.Parse(payload.c_str());
|
162
170
|
if (!ok)
|
@@ -164,11 +172,10 @@ void {{stinger.cpp.client_class_name}}::_handle{{method_name|UpperCamelCase}}Res
|
|
164
172
|
//Log("Could not JSON parse {{method_name}} signal payload.");
|
165
173
|
throw std::runtime_error(rapidjson::GetParseError_En(ok.Code()));
|
166
174
|
}
|
167
|
-
|
168
175
|
if (!doc.IsObject()) {
|
169
176
|
throw std::runtime_error("Received payload is not an object");
|
170
177
|
}
|
171
|
-
|
178
|
+
{%endif%}
|
172
179
|
boost::uuids::uuid correlationIdUuid = boost::lexical_cast<boost::uuids::uuid>(correlationId);
|
173
180
|
auto promiseItr = _pending{{method_name|UpperCamelCase}}MethodCalls.find(correlationIdUuid);
|
174
181
|
if (promiseItr != _pending{{method_name|UpperCamelCase}}MethodCalls.end())
|
@@ -204,4 +211,70 @@ void {{stinger.cpp.client_class_name}}::_handle{{method_name|UpperCamelCase}}Res
|
|
204
211
|
|
205
212
|
std::cout << "End of response handler for " << topic << std::endl;
|
206
213
|
}
|
207
|
-
{%endfor%}
|
214
|
+
{%endfor%}{# end for each method #}
|
215
|
+
{%for prop_name, prop in stinger.properties.items()%}
|
216
|
+
void {{stinger.cpp.client_class_name}}::_receive{{prop_name | UpperCamelCase}}PropertyUpdate(const std::string& topic, const std::string& payload, boost::optional<int> optPropertyVersion)
|
217
|
+
{
|
218
|
+
rapidjson::Document doc;
|
219
|
+
rapidjson::ParseResult ok = doc.Parse(payload.c_str());
|
220
|
+
if (!ok)
|
221
|
+
{
|
222
|
+
//Log("Could not JSON parse {{prop_name}} property update payload.");
|
223
|
+
throw std::runtime_error(rapidjson::GetParseError_En(ok.Code()));
|
224
|
+
}
|
225
|
+
|
226
|
+
if (!doc.IsObject()) {
|
227
|
+
throw std::runtime_error("Received {{prop_name}} payload is not an object");
|
228
|
+
}
|
229
|
+
{{prop.name | UpperCamelCase}}Property tempValue;
|
230
|
+
{{deser.deserialize('tempValue', prop.arg_list, 'doc') | indent(4)}}
|
231
|
+
|
232
|
+
{ // Scope lock
|
233
|
+
std::lock_guard<std::mutex> lock(_{{prop_name | lowerCamelCase}}PropertyMutex);
|
234
|
+
_{{prop_name | lowerCamelCase}}Property = tempValue;
|
235
|
+
_last{{prop_name | UpperCamelCase}}PropertyVersion = optPropertyVersion ? *optPropertyVersion : -1;
|
236
|
+
}
|
237
|
+
// Notify all registered callbacks.
|
238
|
+
{ // Scope lock
|
239
|
+
std::lock_guard<std::mutex> lock(_{{prop_name | lowerCamelCase}}PropertyCallbacksMutex);
|
240
|
+
for (const auto& cb : _{{prop_name | lowerCamelCase}}PropertyCallbacks)
|
241
|
+
{
|
242
|
+
// Don't need a mutex since we're using tempValue.
|
243
|
+
{%if prop.arg_list | length > 1 %}
|
244
|
+
cb({%for arg in prop.arg_list %}tempValue.{{arg.name}}{%if not loop.last%}, {%endif%}{%endfor%});
|
245
|
+
{%else %}
|
246
|
+
cb(tempValue);
|
247
|
+
{%endif %}
|
248
|
+
}
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
boost::optional<{{prop_value_type(prop)}}> {{stinger.cpp.client_class_name}}::get{{prop_name | UpperCamelCase}}Property() const
|
253
|
+
{
|
254
|
+
std::lock_guard<std::mutex> lock(_{{prop_name | lowerCamelCase}}PropertyMutex);
|
255
|
+
return _{{prop_name | lowerCamelCase}}Property;
|
256
|
+
}
|
257
|
+
|
258
|
+
void {{stinger.cpp.client_class_name}}::register{{prop_name | UpperCamelCase}}PropertyCallback(const std::function<void({{ar.methodParams(prop.arg_list)}})>& cb)
|
259
|
+
{
|
260
|
+
std::lock_guard<std::mutex> lock(_{{prop_name | lowerCamelCase}}PropertyCallbacksMutex);
|
261
|
+
_{{prop_name | lowerCamelCase}}PropertyCallbacks.push_back(cb);
|
262
|
+
}
|
263
|
+
{% if not prop.read_only %}
|
264
|
+
boost::future<bool> {{stinger.cpp.client_class_name}}::update{{prop_name | UpperCamelCase}}Property({{ar.methodParams(prop.arg_list)}}) const
|
265
|
+
{
|
266
|
+
|
267
|
+
rapidjson::Document doc;
|
268
|
+
doc.SetObject();
|
269
|
+
{%for item in prop.arg_list %}
|
270
|
+
{{ser.addToValue('doc', item, 'doc.GetAllocator()') | indent(4)}}
|
271
|
+
{%endfor %}
|
272
|
+
rapidjson::StringBuffer buf;
|
273
|
+
rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
|
274
|
+
doc.Accept(writer);
|
275
|
+
MqttProperties mqttProps;
|
276
|
+
return _broker->Publish("{{prop.update_topic}}", buf.GetString(), 1, false, mqttProps);
|
277
|
+
|
278
|
+
}
|
279
|
+
{%endif%}
|
280
|
+
{% endfor %} {# for properties #}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
{% import "partials/deserialize.jinja2" as deser %}
|
2
|
+
{% import "partials/serialize.jinja2" as ser %}
|
3
|
+
#include "property_structs.hpp"
|
4
|
+
#include <rapidjson/document.h>
|
5
|
+
|
6
|
+
{%for prop_name, prop in stinger.properties.items()%}
|
7
|
+
{%- if prop.arg_list| length > 1 %}
|
8
|
+
{{prop.name | UpperCamelCase}}Property {{prop.name | UpperCamelCase}}Property::FromRapidJsonObject(const rapidjson::Value& jsonObj)
|
9
|
+
{
|
10
|
+
{{prop.name | UpperCamelCase}}Property {{prop.name | lowerCamelCase }};
|
11
|
+
{{deser.deserialize(prop.name|lowerCamelCase, prop.arg_list, 'jsonObj') | indent(4)}}
|
12
|
+
|
13
|
+
return {{prop.name | lowerCamelCase}};
|
14
|
+
};
|
15
|
+
|
16
|
+
rapidjson::Value {{prop.name | UpperCamelCase}}Property::ToRapidJsonObject(rapidjson::Document::AllocatorType& allocator) const
|
17
|
+
{
|
18
|
+
rapidjson::Value obj(rapidjson::kObjectType);
|
19
|
+
{%for arg in prop.arg_list%}
|
20
|
+
{{ser.addToValue('obj', arg, 'allocator') | indent(4)}}
|
21
|
+
{%- endfor %}
|
22
|
+
return obj;
|
23
|
+
}
|
24
|
+
{%- endif %}
|
25
|
+
{% endfor %}
|
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
{% import "partials/serialize.jinja2" as ser %}
|
3
|
+
|
2
4
|
#include <vector>
|
3
5
|
#include <iostream>
|
4
6
|
#include <boost/format.hpp>
|
@@ -19,9 +21,12 @@ constexpr const char {{stinger.cpp.server_class_name}}::NAME[];
|
|
19
21
|
constexpr const char {{stinger.cpp.server_class_name}}::INTERFACE_VERSION[];
|
20
22
|
|
21
23
|
{{stinger.cpp.server_class_name}}::{{stinger.cpp.server_class_name}}(std::shared_ptr<IBrokerConnection> broker) : _broker(broker) {
|
22
|
-
_broker->AddMessageCallback([this](
|
24
|
+
_broker->AddMessageCallback([this](
|
25
|
+
const std::string& topic,
|
26
|
+
const std::string& payload,
|
27
|
+
const MqttProperties& mqttProps)
|
23
28
|
{
|
24
|
-
_receiveMessage(topic, payload,
|
29
|
+
_receiveMessage(topic, payload, mqttProps);
|
25
30
|
});
|
26
31
|
{%for method in stinger.methods.values()%}
|
27
32
|
_broker->Subscribe("{{method.topic}}", 2);
|
@@ -31,8 +36,7 @@ constexpr const char {{stinger.cpp.server_class_name}}::INTERFACE_VERSION[];
|
|
31
36
|
void {{stinger.cpp.server_class_name}}::_receiveMessage(
|
32
37
|
const std::string& topic,
|
33
38
|
const std::string& payload,
|
34
|
-
const
|
35
|
-
const boost::optional<std::string> optResponseTopic)
|
39
|
+
const MqttProperties& mqttProps)
|
36
40
|
{
|
37
41
|
{%for method_name, method in stinger.methods.items()%}
|
38
42
|
if (_broker->TopicMatchesSubscription(topic, "{{method.topic}}"))
|
@@ -53,7 +57,7 @@ void {{stinger.cpp.server_class_name}}::_receiveMessage(
|
|
53
57
|
throw std::runtime_error("Received payload is not an object");
|
54
58
|
}
|
55
59
|
|
56
|
-
_call{{method_name | UpperCamelCase}}Handler(topic, doc,
|
60
|
+
_call{{method_name | UpperCamelCase}}Handler(topic, doc, mqttProps.correlationId, mqttProps.responseTopic);
|
57
61
|
}
|
58
62
|
}
|
59
63
|
catch (const boost::bad_lexical_cast&)
|
@@ -71,29 +75,14 @@ boost::future<bool> {{stinger.cpp.server_class_name}}::emit{{sig_name | UpperCam
|
|
71
75
|
{
|
72
76
|
rapidjson::Document doc;
|
73
77
|
doc.SetObject();
|
74
|
-
{%macro addToDoc(arg)%}
|
75
|
-
{%-if arg.optional%}if ({{arg.name}}){%endif%}
|
76
|
-
{%-if arg.arg_type.name.lower() == 'primitive'%}
|
77
|
-
{%-if arg.type.name.lower() == 'string'%}
|
78
|
-
{ // restrict scope
|
79
|
-
rapidjson::Value tempStringValue;
|
80
|
-
tempStringValue.SetString({{arg.name}}{%-if arg.optional%}->{%else%}.{%endif%}c_str(), {{arg.name}}.size(), doc.GetAllocator());
|
81
|
-
doc.AddMember("{{arg.name}}", tempStringValue, doc.GetAllocator());
|
82
|
-
}
|
83
|
-
{%-else%}
|
84
|
-
doc.AddMember("{{arg.name}}", {%-if arg.optional%}*{%endif%}{{arg.name}}, doc.GetAllocator());
|
85
|
-
{%-endif%}
|
86
|
-
{%-elif arg.arg_type.name.lower() == 'enum'%}
|
87
|
-
doc.AddMember("{{arg.name}}", static_cast<int>({%-if arg.optional%}*{%endif%}{{arg.name}}), doc.GetAllocator());
|
88
|
-
{%-endif-%}
|
89
|
-
{%-endmacro%}
|
90
78
|
{%-for arg in sig.arg_list%}
|
91
|
-
{{
|
92
|
-
{
|
79
|
+
{{ser.addToValue('doc', arg, 'doc.GetAllocator()') | indent}}
|
80
|
+
{%-endfor%}
|
93
81
|
rapidjson::StringBuffer buf;
|
94
82
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
|
95
83
|
doc.Accept(writer);
|
96
|
-
|
84
|
+
MqttProperties mqttProps;
|
85
|
+
return _broker->Publish("{{sig.topic}}", buf.GetString(), 1, false, mqttProps);
|
97
86
|
}
|
98
87
|
{%endfor%}
|
99
88
|
|
@@ -163,7 +152,10 @@ void {{stinger.cpp.server_class_name}}::_call{{method_name | UpperCamelCase}}Han
|
|
163
152
|
rapidjson::StringBuffer buf;
|
164
153
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
|
165
154
|
responseJson.Accept(writer);
|
166
|
-
|
155
|
+
MqttProperties mqttProps;
|
156
|
+
mqttProps.correlationId = optCorrelationId;
|
157
|
+
mqttProps.resultCode = MethodResultCode::SUCCESS;
|
158
|
+
_broker->Publish(*optResponseTopic, buf.GetString(), 2, false, mqttProps);
|
167
159
|
}
|
168
160
|
}
|
169
161
|
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{% import "partials/deserialize.jinja2" as deser %}
|
2
|
+
#include "structs.hpp"
|
3
|
+
|
4
|
+
|
5
|
+
{%for istruct_name, istruct in stinger.structs.items() %}
|
6
|
+
{{istruct_name | UpperCamelCase }} {{istruct_name | UpperCamelCase }}::FromRapidJsonObject(const rapidjson::Value& jsonObj)
|
7
|
+
{
|
8
|
+
{{istruct_name | UpperCamelCase }} {{istruct_name | lowerCamelCase }};
|
9
|
+
{{deser.deserialize(istruct_name|lowerCamelCase, istruct.members, 'jsonObj') | indent(4)}}
|
10
|
+
|
11
|
+
return {{istruct_name | lowerCamelCase}};
|
12
|
+
};
|
13
|
+
{%endfor%}
|
@@ -1,14 +1,14 @@
|
|
1
1
|
const clientId = "{{stinger.name}}-web-" + new Date().getTime();
|
2
2
|
|
3
|
-
const
|
4
|
-
|
3
|
+
const responseTopic = "client/" + clientId + "/responses";
|
4
|
+
var responseSubscriptionId = null;
|
5
5
|
|
6
6
|
function makeRequestProperties() {
|
7
7
|
const correlationData = Math.random().toString(16).substr(2, 8);
|
8
8
|
return {
|
9
9
|
"contentType": "application/json",
|
10
10
|
"correlationData": correlationData,
|
11
|
-
"responseTopic": responseTopic
|
11
|
+
"responseTopic": responseTopic
|
12
12
|
}
|
13
13
|
}
|
14
14
|
|
@@ -22,17 +22,58 @@ app.controller("myCtrl", function ($scope, $filter, $location) {
|
|
22
22
|
|
23
23
|
$scope.timePattern = new RegExp("^[0-2][0-9]:[0-5][0-9]$");
|
24
24
|
$scope.online = false;
|
25
|
+
|
26
|
+
$scope.enums = {
|
27
|
+
{%-for enum_name, enum in stinger.enums.items() %}
|
28
|
+
// {{enum}}
|
29
|
+
"{{enum_name | snake_case}}": [
|
30
|
+
{%-for e in enum.values %}
|
31
|
+
{"name": "{{e}}", "id": {{loop.index}} }{%if not loop.last%},{%endif%}
|
32
|
+
{%endfor-%}
|
33
|
+
]{%if not loop.last%},{%endif%}
|
34
|
+
{%endfor-%} };
|
35
|
+
|
25
36
|
$scope.signals = { {%-for sig_name, signal in stinger.signals.items() %}
|
26
|
-
"{{sig_name |
|
37
|
+
"{{sig_name | snake_case}}": {
|
27
38
|
"subscription_id": null,
|
28
39
|
"name": "{{sig_name}}",
|
29
|
-
"received":
|
40
|
+
"received": null,
|
41
|
+
"received_time": null,
|
30
42
|
"mqtt_topic": "{{signal.topic}}"
|
31
43
|
}{%if not loop.last%},{%endif%}
|
32
44
|
{%endfor-%} };
|
33
45
|
|
34
|
-
$scope.properties = {
|
46
|
+
$scope.properties = { {%-for prop_name, prop in stinger.properties.items() %}
|
47
|
+
"{{prop_name | snake_case}}": {
|
48
|
+
"subscription_id": null,
|
49
|
+
"name": "{{prop_name}}",
|
50
|
+
"received": { {%for arg in prop.arg_list %}
|
51
|
+
"{{arg.name|snake_case}}": {%if arg.type == "argtype.primitive"%}{%else%}{ {%for member in arg.members %}
|
52
|
+
"{{member.name|snake_case}}": "{{member.value}}"{%if not loop.last%},{%endif%}
|
53
|
+
{%endfor%} }{%endif%}{%if not loop.last%},{%endif%}
|
54
|
+
{%endfor%} },
|
55
|
+
"mqtt_topic": "{{prop.value_topic}}"{%if not prop.read_only %},
|
56
|
+
"update_topic": "{{prop.update_topic}}"{%endif%}
|
57
|
+
}{%if not loop.last%},{%endif%}
|
58
|
+
{%endfor-%} };
|
35
59
|
|
60
|
+
$scope.methods = {
|
61
|
+
{%-for method_name, method in stinger.methods.items() %}
|
62
|
+
"{{method_name | snake_case}}": {
|
63
|
+
"name": "{{method_name}}",
|
64
|
+
"mqtt_topic": "{{method.topic}}",
|
65
|
+
"response_topic": "{{method.response_topic('"+clientId+"')}}",
|
66
|
+
"pending_correlation_id": null,
|
67
|
+
"args": { {%-for arg in method.arg_list %}
|
68
|
+
"{{arg.name|snake_case}}": {
|
69
|
+
"type": "{{arg.type}}",
|
70
|
+
"value": null
|
71
|
+
}{%if not loop.last%},{%endif%}
|
72
|
+
{%endfor-%} },
|
73
|
+
"received": null,
|
74
|
+
"received_time": null
|
75
|
+
}{%if not loop.last%},{%endif%}
|
76
|
+
{%-endfor%}
|
36
77
|
};
|
37
78
|
|
38
79
|
$scope.console = {
|
@@ -63,26 +104,17 @@ app.controller("myCtrl", function ($scope, $filter, $location) {
|
|
63
104
|
console.log(name + " Sending to " + topic);
|
64
105
|
console.log(payload);
|
65
106
|
let props = makeRequestProperties();
|
66
|
-
props
|
67
107
|
$scope.console.requests.unshift({"name":name, "correlationData":props.correlationData, "topic": topic, "payload": payload, "response": null, "requestTime": Date.now()});
|
68
108
|
client.publish(topic, payload, { "qos": qos, retain: false, properties: props});
|
69
109
|
return props.correlationData;
|
70
110
|
}
|
71
111
|
|
72
112
|
client.on('message', function(topic, message, packet) {
|
73
|
-
|
74
|
-
|
113
|
+
|
75
114
|
const subid = packet.properties.subscriptionIdentifier;
|
76
115
|
|
77
|
-
|
78
|
-
|
79
|
-
console.log("Signal index: " + signal_index);
|
80
|
-
$scope.data.signals[signal_index] = JSON.parse(message.toString());
|
81
|
-
} else if (subid >= propertySubIdStart && subid < propertySubIdStart + {{stinger.properties|length}}) {
|
82
|
-
const prop_index = subid - propertySubIdStart;
|
83
|
-
console.log("Property index: " + prop_index);
|
84
|
-
$scope.data.properties[prop_index] = JSON.parse(message.toString());
|
85
|
-
}
|
116
|
+
console.log("Message Arrived: " + topic + " (" + subid + ")");
|
117
|
+
console.log($scope.properties);
|
86
118
|
|
87
119
|
var obj;
|
88
120
|
if (message.toString().length == 0) {
|
@@ -92,34 +124,103 @@ app.controller("myCtrl", function ($scope, $filter, $location) {
|
|
92
124
|
}
|
93
125
|
console.log(obj);
|
94
126
|
|
127
|
+
for (const key in $scope.signals) {
|
128
|
+
if (!$scope.signals.hasOwnProperty(key)) continue;
|
129
|
+
const sig = $scope.signals[key];
|
130
|
+
if (sig.subscription_id == subid) {
|
131
|
+
sig.received = obj;
|
132
|
+
sig.received_time = new Date();
|
133
|
+
}
|
134
|
+
}
|
135
|
+
for (const key in $scope.properties) {
|
136
|
+
if (!$scope.properties.hasOwnProperty(key)) continue;
|
137
|
+
const prop = $scope.properties[key];
|
138
|
+
if (prop.subscription_id == subid) {
|
139
|
+
prop.received = obj;
|
140
|
+
console.log("Set property received object to ", prop.received);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
for (const key in $scope.methods) {
|
144
|
+
if (!$scope.methods.hasOwnProperty(key)) continue;
|
145
|
+
const method = $scope.methods[key];
|
146
|
+
if (responseSubscriptionId == subid) {
|
147
|
+
if (packet.properties.correlationData && method.pending_correlation_id == packet.properties.correlationData) {
|
148
|
+
method.received = obj;
|
149
|
+
method.received_time = new Date();
|
150
|
+
for (let i=0; i<$scope.console.requests.length; i++) {
|
151
|
+
const req = $scope.console.requests[i];
|
152
|
+
if (req.correlationData == packet.properties.correlationData) {
|
153
|
+
req.response = obj;
|
154
|
+
req.responseTime = Date.now();
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
95
161
|
$scope.$apply();
|
96
162
|
});
|
97
163
|
|
98
164
|
client.on('connect', function() {
|
165
|
+
$scope.online = true;
|
166
|
+
|
167
|
+
var subscription_count = 10;
|
99
168
|
console.log("Connected with ", client);
|
100
|
-
|
101
|
-
|
169
|
+
|
170
|
+
var responseSubscriptionId = subscription_count++;
|
171
|
+
const responseSubOpts = {
|
102
172
|
"qos": 1,
|
103
173
|
"properties": {
|
104
|
-
"subscriptionIdentifier":
|
174
|
+
"subscriptionIdentifier": responseSubscriptionId
|
105
175
|
}
|
106
176
|
};
|
107
|
-
client.subscribe(
|
108
|
-
console.log("Subscribing to
|
109
|
-
|
110
|
-
{%for
|
111
|
-
const {{
|
177
|
+
client.subscribe(responseTopic, responseSubOpts);
|
178
|
+
console.log("Subscribing to response topic " + responseTopic + " with id " + responseSubscriptionId);
|
179
|
+
|
180
|
+
{%for signal_name, signal in stinger.signals.items() %}
|
181
|
+
const {{signal_name|snake_case}}_sub_opts = {
|
112
182
|
"qos": 1,
|
113
183
|
"properties": {
|
114
|
-
"subscriptionIdentifier":
|
184
|
+
"subscriptionIdentifier": subscription_count
|
115
185
|
}
|
116
186
|
};
|
117
|
-
|
118
|
-
|
187
|
+
$scope.signals["{{signal_name | lowerCamelCase}}"].subscription_id = subscription_count;
|
188
|
+
client.subscribe("{{signal.topic}}", {{signal_name|snake_case}}_sub_opts);
|
189
|
+
console.log("Subscribing to signal {{signal.topic}} with id ", subscription_count);
|
190
|
+
subscription_count++;
|
119
191
|
{%endfor%}
|
192
|
+
|
193
|
+
for (const key in $scope.properties) {
|
194
|
+
if (!$scope.properties.hasOwnProperty(key)) continue;
|
195
|
+
var sub_id = subscription_count++;
|
196
|
+
const prop_sub_opts = {
|
197
|
+
"qos": 1,
|
198
|
+
"properties": {
|
199
|
+
"subscriptionIdentifier": sub_id
|
200
|
+
}
|
201
|
+
};
|
202
|
+
$scope.properties[key].subscription_id = sub_id;
|
203
|
+
client.subscribe($scope.properties[key].mqtt_topic, prop_sub_opts);
|
204
|
+
console.log("Subscribing to property " + $scope.properties[key].mqtt_topic + " with id " + $scope.properties[key].subscription_id);
|
205
|
+
}
|
206
|
+
|
120
207
|
subscription_state = 1;
|
121
208
|
$scope.$apply();
|
122
209
|
});
|
123
210
|
|
211
|
+
$scope.updateProperty = function(prop) {
|
212
|
+
const payload = JSON.stringify(prop.received);
|
213
|
+
publish("Property Update", prop.update_topic, payload, 1);
|
214
|
+
};
|
124
215
|
|
216
|
+
$scope.callMethod = function(method) {
|
217
|
+
const payload = {};
|
218
|
+
for (const key in method.args) {
|
219
|
+
if (!method.args.hasOwnProperty(key)) continue;
|
220
|
+
payload[key] = method.args[key].value;
|
221
|
+
}
|
222
|
+
const payload_str = JSON.stringify(payload);
|
223
|
+
console.log("Method Call", method.mqtt_topic, payload_str, 1);
|
224
|
+
method.pending_correlation_id = publish("Method Call", method.mqtt_topic, payload_str, 1);
|
225
|
+
};
|
125
226
|
});
|