stinger-ipc 0.0.5__py3-none-any.whl → 0.0.8__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.5.dist-info → stinger_ipc-0.0.8.dist-info}/METADATA +2 -2
- {stinger_ipc-0.0.5.dist-info → stinger_ipc-0.0.8.dist-info}/RECORD +27 -23
- {stinger_ipc-0.0.5.dist-info → stinger_ipc-0.0.8.dist-info}/entry_points.txt +1 -0
- stingeripc/components.py +5 -5
- stingeripc/lang_symb.py +21 -4
- stingeripc/templates/html/app.js.jinja2 +125 -0
- stingeripc/templates/html/index.html.jinja2 +43 -0
- stingeripc/templates/html/styles.css.jinja2 +187 -0
- stingeripc/templates/rust/Cargo.toml.jinja2 +1 -1
- stingeripc/templates/rust/client/Cargo.toml.jinja2 +7 -5
- stingeripc/templates/rust/client/examples/client.rs.jinja2 +9 -10
- stingeripc/templates/rust/client/src/lib.rs.jinja2 +112 -55
- stingeripc/templates/rust/{connection → payloads}/Cargo.toml.jinja2 +8 -4
- stingeripc/templates/rust/{connection → payloads}/examples/pub_and_recv.rs.jinja2 +11 -11
- stingeripc/templates/rust/payloads/src/lib.rs.jinja2 +4 -0
- stingeripc/templates/rust/{connection → payloads}/src/payloads.rs.jinja2 +10 -2
- stingeripc/templates/rust/server/Cargo.toml.jinja2 +4 -4
- stingeripc/templates/rust/server/examples/server.rs.jinja2 +8 -12
- stingeripc/templates/rust/server/src/lib.rs.jinja2 +92 -69
- stingeripc/tools/cli.py +73 -0
- stingeripc/tools/markdown_generator.py +4 -2
- stingeripc/tools/python_generator.py +12 -10
- stingeripc/tools/rust_generator.py +46 -27
- stingeripc/templates/rust/connection/src/lib.rs.jinja2 +0 -262
- {stinger_ipc-0.0.5.dist-info → stinger_ipc-0.0.8.dist-info}/WHEEL +0 -0
- {stinger_ipc-0.0.5.dist-info → stinger_ipc-0.0.8.dist-info}/licenses/LICENSE +0 -0
- {stinger_ipc-0.0.5.dist-info → stinger_ipc-0.0.8.dist-info}/top_level.txt +0 -0
- /stingeripc/templates/rust/{connection → payloads}/src/handler.rs.jinja2 +0 -0
@@ -1,11 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: stinger-ipc
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.8
|
4
4
|
Summary: Tools to create code to do IPC over MQTT
|
5
5
|
Requires-Python: >=3.12
|
6
6
|
Description-Content-Type: text/markdown
|
7
7
|
License-File: LICENSE
|
8
|
-
Requires-Dist: jacobs-jinja-too>=0.
|
8
|
+
Requires-Dist: jacobs-jinja-too>=0.2.4
|
9
9
|
Requires-Dist: packaging>=25.0
|
10
10
|
Requires-Dist: pydantic>=2.11.7
|
11
11
|
Requires-Dist: pyyaml>=6.0.2
|
@@ -1,12 +1,12 @@
|
|
1
|
-
stinger_ipc-0.0.
|
1
|
+
stinger_ipc-0.0.8.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
|
2
2
|
stingeripc/__init__.py,sha256=PTr5WfMfB-GL4vp3-XMU8IwGv3Q5RXQ24H7JuEo3hdk,133
|
3
3
|
stingeripc/args.py,sha256=x3P8GRu9-jyiMl62t0FPqbWY18FbhMVN4eSa2UzUv6c,3960
|
4
4
|
stingeripc/asyncapi.py,sha256=DJZuz_LiQEJjQGlnfRtgOToWVD55uLw5ZoiZ95-bxZc,23291
|
5
|
-
stingeripc/components.py,sha256=
|
5
|
+
stingeripc/components.py,sha256=B08bXGrhVy90i3S67uS1kXDC3jQb_2bQay_LbgzWhQ4,38426
|
6
6
|
stingeripc/connection.py,sha256=DfBG9LKaEuGacmX5NPphDabJqJmO3tVUg8Oa-efCd7w,184
|
7
7
|
stingeripc/exceptions.py,sha256=nX5Xl4KjPTfSRTVZIB9NkgM0g_6auXgr5fTyunCZy5Q,51
|
8
8
|
stingeripc/interface.py,sha256=ypt4T7hTH7ePKLy3JCl1b1ggyH5T38m68Gt0m_5VOBM,1558
|
9
|
-
stingeripc/lang_symb.py,sha256=
|
9
|
+
stingeripc/lang_symb.py,sha256=MOIMj9_mj6_8IADXCJf-EvlZ5d7Y6yR4QWsCONcw-T8,3331
|
10
10
|
stingeripc/topic.py,sha256=mIL6Abf3fcI0yeSGj_o9ulV6xFNIfyfwGZ5joEVXyzE,2404
|
11
11
|
stingeripc/templates/cpp/CMakeLists.txt.jinja2,sha256=jXlF2GOAt1mBsm6JqPZGaRr53NV5oJsfTd6nedeJ-GA,945
|
12
12
|
stingeripc/templates/cpp/examples/client_main.cpp.jinja2,sha256=llUcuT4_R4SA5Nhpg6pRjs8nMogD5M21n6_aaewTJwE,2630
|
@@ -22,6 +22,9 @@ stingeripc/templates/cpp/include/structs.hpp.jinja2,sha256=DJAAq07DWJmYAEI9An5yx
|
|
22
22
|
stingeripc/templates/cpp/src/broker.cpp.jinja2,sha256=32bfKFJIzHe8w4JKZKjJ-wv8vVrYtOULyRK8f2lF1ow,9345
|
23
23
|
stingeripc/templates/cpp/src/client.cpp.jinja2,sha256=lfIbb-Usnru44-5EmrAGzjFiLqkoiSt-9VYkIrugXSI,9010
|
24
24
|
stingeripc/templates/cpp/src/server.cpp.jinja2,sha256=hs27uqLCwYR_1cvhwZwGiXTpEnsoBiGlMJE0pbY5cPg,7765
|
25
|
+
stingeripc/templates/html/app.js.jinja2,sha256=07USEiNgd1euaahPTz3tfcV-aFKEBX83NAVgYVbvr98,4110
|
26
|
+
stingeripc/templates/html/index.html.jinja2,sha256=egY_0riMki6czNQLTldOMlRdapFKNMouDfwMIcnDtuo,2155
|
27
|
+
stingeripc/templates/html/styles.css.jinja2,sha256=C0-ZZk4SIzG9dv9x9MrfhHrtkHBj7jRBFIQ98BFlrcg,3323
|
25
28
|
stingeripc/templates/markdown/index.md.jinja2,sha256=yB1Jpawc1VdBAzmnCI0ikdvVlcjZXf-2xRs159XSnHg,6432
|
26
29
|
stingeripc/templates/python/__init__.py.jinja2,sha256=jdZ07ogzJLOgzqqkHjj2_8hld9uBDnvB1DXPXnWkt98,22
|
27
30
|
stingeripc/templates/python/client.py.jinja2,sha256=lUlnh-Z2ulDaomx-bR7RAgovmZ4QYLjck0c_885x8DY,16461
|
@@ -30,24 +33,25 @@ stingeripc/templates/python/interface_types.py.jinja2,sha256=BcCD0uCzDn1TAn1IvWh
|
|
30
33
|
stingeripc/templates/python/method_codes.py.jinja2,sha256=74i8iKk4Fu9_nE2SYTRrRK2G4mogfJx88ihbmjyfYVQ,1089
|
31
34
|
stingeripc/templates/python/pyproject.toml.jinja2,sha256=R-rgSv6RTdgPINvhCwJ180Vzjy9-WkqtLbLgnCov3CI,195
|
32
35
|
stingeripc/templates/python/server.py.jinja2,sha256=pxjzLPE7k3DG6zE-zXyK_I16ZF8k-xgbdh_182Fx_E8,11217
|
33
|
-
stingeripc/templates/rust/Cargo.toml.jinja2,sha256=
|
34
|
-
stingeripc/templates/rust/client/Cargo.toml.jinja2,sha256=
|
35
|
-
stingeripc/templates/rust/client/examples/client.rs.jinja2,sha256=
|
36
|
-
stingeripc/templates/rust/client/src/lib.rs.jinja2,sha256=
|
37
|
-
stingeripc/templates/rust/
|
38
|
-
stingeripc/templates/rust/
|
39
|
-
stingeripc/templates/rust/
|
40
|
-
stingeripc/templates/rust/
|
41
|
-
stingeripc/templates/rust/
|
42
|
-
stingeripc/templates/rust/server/Cargo.toml.jinja2,sha256=
|
43
|
-
stingeripc/templates/rust/server/examples/server.rs.jinja2,sha256=
|
44
|
-
stingeripc/templates/rust/server/src/lib.rs.jinja2,sha256=
|
36
|
+
stingeripc/templates/rust/Cargo.toml.jinja2,sha256=teIu5y2AeqSkk0eUPT8CemvzmhRoblCUP5jdmonLfY4,70
|
37
|
+
stingeripc/templates/rust/client/Cargo.toml.jinja2,sha256=k_WodPg-gJTnRI4m9P38AfN5tIaztxl3qQY9fwiNWXk,825
|
38
|
+
stingeripc/templates/rust/client/examples/client.rs.jinja2,sha256=pMLR-xyEJrK4289XUbFEB18HKe3kaRJDoeFBQ89SLU4,2075
|
39
|
+
stingeripc/templates/rust/client/src/lib.rs.jinja2,sha256=7GGy_IBH-DBHIZUCvvBq1xbTTVVMczvx5W-i0qO_fvw,15451
|
40
|
+
stingeripc/templates/rust/payloads/Cargo.toml.jinja2,sha256=t6WQ5BCBvjagCW8AgK4VYSNjW2OZCX30KQTXk27SGwI,739
|
41
|
+
stingeripc/templates/rust/payloads/examples/pub_and_recv.rs.jinja2,sha256=cIbunwEwYGbkRO1lzi2nGNX2dGdFhAJ2ZZqFhphY7CY,1461
|
42
|
+
stingeripc/templates/rust/payloads/src/handler.rs.jinja2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
|
+
stingeripc/templates/rust/payloads/src/lib.rs.jinja2,sha256=3vBn2OGm_j7BoyHRHLcH1e0hKRBiqtbgHsz04rTaVMM,86
|
44
|
+
stingeripc/templates/rust/payloads/src/payloads.rs.jinja2,sha256=1PUSzmHLMBYsVaCR8gOMdHWK8dmODmLM3WSu9iysN-c,4380
|
45
|
+
stingeripc/templates/rust/server/Cargo.toml.jinja2,sha256=Akr0Gxxql5o4QeKabQyz24f20amPoB2LVq7iMa_qCZc,541
|
46
|
+
stingeripc/templates/rust/server/examples/server.rs.jinja2,sha256=9no7UyiGEaqDdqN6YiYScYXvYPgoB2IsDrTF_diVVWM,3526
|
47
|
+
stingeripc/templates/rust/server/src/lib.rs.jinja2,sha256=dJL5YY776laUmFa4-LltUv6hvxfRkjcWWgj7hGRZ1ps,14831
|
45
48
|
stingeripc/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
46
|
-
stingeripc/tools/
|
47
|
-
stingeripc/tools/
|
48
|
-
stingeripc/tools/
|
49
|
-
|
50
|
-
stinger_ipc-0.0.
|
51
|
-
stinger_ipc-0.0.
|
52
|
-
stinger_ipc-0.0.
|
53
|
-
stinger_ipc-0.0.
|
49
|
+
stingeripc/tools/cli.py,sha256=oLfVQx4EqRgZ2AH9Xl7X6neXle-aJE55bSXTEvH7RDE,2303
|
50
|
+
stingeripc/tools/markdown_generator.py,sha256=HVEWcMjAfVnuWY29kxfAW1mvSxQSF-rdYFA2kWdLOn0,1174
|
51
|
+
stingeripc/tools/python_generator.py,sha256=GJwGI6DntkJPJjHN4xSeTD60KgY32gI43IvIByxWSsw,1845
|
52
|
+
stingeripc/tools/rust_generator.py,sha256=9E7SMDM-iHE3O26QI3ieAHIInlrLepWMAFRnflKk3KI,2235
|
53
|
+
stinger_ipc-0.0.8.dist-info/METADATA,sha256=G0NbCW1CGNCEuue1ZCNaxZI-5QVuvjO6cbpCwf-X6XU,6037
|
54
|
+
stinger_ipc-0.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
55
|
+
stinger_ipc-0.0.8.dist-info/entry_points.txt,sha256=bh8k8mvtAog4MKTd82ALSHqQkuD069VrZ-vNlde6XjE,204
|
56
|
+
stinger_ipc-0.0.8.dist-info/top_level.txt,sha256=mSNwAf83_1qiTP_vu7XEPBrZu-fDusT1FFyQZzCrRcU,11
|
57
|
+
stinger_ipc-0.0.8.dist-info/RECORD,,
|
stingeripc/components.py
CHANGED
@@ -203,9 +203,9 @@ class ArgEnum(Arg):
|
|
203
203
|
retval = f"{self._enum.class_name}::{stringcase.constcase(value)}"
|
204
204
|
elif lang == "rust":
|
205
205
|
if self.optional:
|
206
|
-
retval = f"Some(
|
206
|
+
retval = f"Some({self._enum.class_name}::{stringmanip.upper_camel_case(value)})"
|
207
207
|
else:
|
208
|
-
retval = f"
|
208
|
+
retval = f"{self._enum.class_name}::{stringmanip.upper_camel_case(value)}"
|
209
209
|
random.setstate(random_state)
|
210
210
|
return retval
|
211
211
|
|
@@ -646,7 +646,7 @@ class Property(InterfaceComponent):
|
|
646
646
|
if len(self._arg_list) == 1:
|
647
647
|
return self._arg_list[0].rust_type
|
648
648
|
else:
|
649
|
-
return f"
|
649
|
+
return f"{self.rust_local_type}"
|
650
650
|
|
651
651
|
@property
|
652
652
|
def arg_list(self) -> list[Arg]:
|
@@ -740,7 +740,7 @@ class InterfaceEnum:
|
|
740
740
|
|
741
741
|
@property
|
742
742
|
def rust_type(self) -> str:
|
743
|
-
return f"
|
743
|
+
return f"{self.rust_local_type}"
|
744
744
|
|
745
745
|
@property
|
746
746
|
def cpp_type(self) -> str:
|
@@ -811,7 +811,7 @@ class InterfaceStruct:
|
|
811
811
|
|
812
812
|
@property
|
813
813
|
def rust_type(self) -> str:
|
814
|
-
return f"
|
814
|
+
return f"{self.rust_local_type}"
|
815
815
|
|
816
816
|
@property
|
817
817
|
def cpp_type(self) -> str:
|
stingeripc/lang_symb.py
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
|
2
2
|
from jacobsjinjatoo import stringmanip
|
3
|
+
import stringcase
|
3
4
|
|
4
5
|
class PythonSymbols:
|
5
6
|
def __init__(self):
|
6
7
|
...
|
7
8
|
|
8
|
-
@property
|
9
|
-
def package_name(self):
|
10
|
-
return f"{stringmanip.lower_camel_case(self._iface.name).lower()}ipc"
|
11
|
-
|
12
9
|
@property
|
13
10
|
def type_definition_module(self) -> str:
|
14
11
|
return "stinger_types"
|
15
12
|
|
13
|
+
|
16
14
|
class PythonInterfaceSymbols(PythonSymbols):
|
17
15
|
|
18
16
|
def __init__(self, interface):
|
19
17
|
super().__init__()
|
20
18
|
self._iface = interface
|
21
19
|
|
20
|
+
@property
|
21
|
+
def package_name(self):
|
22
|
+
return f"{stringmanip.lower_camel_case(self._iface.name).lower()}ipc"
|
23
|
+
|
22
24
|
@property
|
23
25
|
def client_class_name(self) -> str:
|
24
26
|
""" Name of the python class for the interface client."""
|
@@ -65,6 +67,21 @@ class RustInterfaceSymbols(RustSymbols):
|
|
65
67
|
super().__init__()
|
66
68
|
self._iface = interface
|
67
69
|
|
70
|
+
@property
|
71
|
+
def client_package_name(self) -> str:
|
72
|
+
""" Name of the rust package for the interface client."""
|
73
|
+
return f"{stringcase.snakecase(self._iface.name)}_client"
|
74
|
+
|
75
|
+
@property
|
76
|
+
def server_package_name(self) -> str:
|
77
|
+
""" Name of the rust package for the interface server."""
|
78
|
+
return f"{stringcase.snakecase(self._iface.name)}_server"
|
79
|
+
|
80
|
+
@property
|
81
|
+
def common_package_name(self) -> str:
|
82
|
+
""" Name of the rust package for the interface common types."""
|
83
|
+
return f"{stringcase.snakecase(self._iface.name)}_types"
|
84
|
+
|
68
85
|
@property
|
69
86
|
def client_struct_name(self) -> str:
|
70
87
|
""" Name of the rust struct for the interface client."""
|
@@ -0,0 +1,125 @@
|
|
1
|
+
const clientId = "{{stinger.name}}-web-" + new Date().getTime();
|
2
|
+
|
3
|
+
const signalSubIdStart = 1;
|
4
|
+
const propertySubIdStart = {{10 + stinger.signals|length}};
|
5
|
+
|
6
|
+
function makeRequestProperties() {
|
7
|
+
const correlationData = Math.random().toString(16).substr(2, 8);
|
8
|
+
return {
|
9
|
+
"contentType": "application/json",
|
10
|
+
"correlationData": correlationData,
|
11
|
+
"responseTopic": responseTopic + correlationData
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
var app = angular.module("myApp", []);
|
16
|
+
|
17
|
+
app.controller("myCtrl", function ($scope, $filter, $location) {
|
18
|
+
|
19
|
+
console.log("Running app");
|
20
|
+
|
21
|
+
var subscription_state = 0;
|
22
|
+
|
23
|
+
$scope.timePattern = new RegExp("^[0-2][0-9]:[0-5][0-9]$");
|
24
|
+
$scope.online = false;
|
25
|
+
$scope.signals = { {%-for sig_name, signal in stinger.signals.items() %}
|
26
|
+
"{{sig_name | lowerCamelCase}}": {
|
27
|
+
"subscription_id": null,
|
28
|
+
"name": "{{sig_name}}",
|
29
|
+
"received": [],
|
30
|
+
"mqtt_topic": "{{signal.topic}}"
|
31
|
+
}{%if not loop.last%},{%endif%}
|
32
|
+
{%endfor-%} };
|
33
|
+
|
34
|
+
$scope.properties = {
|
35
|
+
|
36
|
+
};
|
37
|
+
|
38
|
+
$scope.console = {
|
39
|
+
showing: false,
|
40
|
+
requests: []
|
41
|
+
}
|
42
|
+
|
43
|
+
$scope.showoutput = false;
|
44
|
+
$scope.linuxoutput = '';
|
45
|
+
|
46
|
+
const brokerUrl = 'ws://' + location.hostname + ':' + location.port + '/ws'
|
47
|
+
|
48
|
+
const connectOptions = {
|
49
|
+
keepAlive: 60,
|
50
|
+
clientId: clientId,
|
51
|
+
protocolId: 'MQTT',
|
52
|
+
protocolVersion: 5,
|
53
|
+
clean: true
|
54
|
+
};
|
55
|
+
|
56
|
+
var client = mqtt.connect(brokerUrl, connectOptions);
|
57
|
+
|
58
|
+
client.on('close', function() {
|
59
|
+
console.log("Connection Lost");
|
60
|
+
});
|
61
|
+
|
62
|
+
function publish(name, topic, payload, qos) {
|
63
|
+
console.log(name + " Sending to " + topic);
|
64
|
+
console.log(payload);
|
65
|
+
let props = makeRequestProperties();
|
66
|
+
props
|
67
|
+
$scope.console.requests.unshift({"name":name, "correlationData":props.correlationData, "topic": topic, "payload": payload, "response": null, "requestTime": Date.now()});
|
68
|
+
client.publish(topic, payload, { "qos": qos, retain: false, properties: props});
|
69
|
+
return props.correlationData;
|
70
|
+
}
|
71
|
+
|
72
|
+
client.on('message', function(topic, message, packet) {
|
73
|
+
console.log("Message Arrived: " + topic);
|
74
|
+
|
75
|
+
const subid = packet.properties.subscriptionIdentifier;
|
76
|
+
|
77
|
+
if (subid >= signalSubIdStart && subid < propertySubIdStart) {
|
78
|
+
const signal_index = subid - signalSubIdStart;
|
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
|
+
}
|
86
|
+
|
87
|
+
var obj;
|
88
|
+
if (message.toString().length == 0) {
|
89
|
+
obj = null;
|
90
|
+
} else {
|
91
|
+
obj = JSON.parse(message.toString());
|
92
|
+
}
|
93
|
+
console.log(obj);
|
94
|
+
|
95
|
+
$scope.$apply();
|
96
|
+
});
|
97
|
+
|
98
|
+
client.on('connect', function() {
|
99
|
+
console.log("Connected with ", client);
|
100
|
+
{%for signal_name, signal in stinger.signals.items() %}
|
101
|
+
const {{sig_name}}_sub_opts = {
|
102
|
+
"qos": 1,
|
103
|
+
"properties": {
|
104
|
+
"subscriptionIdentifier": (signalSubIdStart + {{loop.index}})
|
105
|
+
}
|
106
|
+
};
|
107
|
+
client.subscribe("{{signal.topic}}", {{sig_name}}_sub_opts);
|
108
|
+
console.log("Subscribing to {{signal.topic}} with id {{loop.index}}");
|
109
|
+
{%endfor%}
|
110
|
+
{%for prop_name, prop in stinger.properties.items() %}
|
111
|
+
const {{prop_name}}_sub_opts = {
|
112
|
+
"qos": 1,
|
113
|
+
"properties": {
|
114
|
+
"subscriptionIdentifier": (propertySubIdStart + {{loop.index}})
|
115
|
+
}
|
116
|
+
};
|
117
|
+
client.subscribe("{{prop.value_topic}}", {{prop_name}}_sub_opts);
|
118
|
+
console.log("Subscribing to {{prop.value_topic}} with id {{loop.index + stinger.signals|length}}");
|
119
|
+
{%endfor%}
|
120
|
+
subscription_state = 1;
|
121
|
+
$scope.$apply();
|
122
|
+
});
|
123
|
+
|
124
|
+
|
125
|
+
});
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Standalone Devices (Demo)</title>
|
5
|
+
<meta charset="UTF-8" />
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
7
|
+
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@7.2.96/css/materialdesignicons.min.css" rel="stylesheet" />
|
8
|
+
<link rel="stylesheet" href="./style.css" />
|
9
|
+
</head>
|
10
|
+
<body ng-app="myApp" ng-controller="myCtrl">
|
11
|
+
<div class="infobox-background" ng-show="!online || showoutput" id="offline">Connecting</div>
|
12
|
+
{%for sig_name, sig in stinger.signals.items() %}
|
13
|
+
<div class="signal-box" id="signal-box-{{ sig_name }}">
|
14
|
+
<h3 class="signal-title">{{ sig_name }}</h3>
|
15
|
+
<div class="signal-doc">{%if sig.documentation %}
|
16
|
+
{%markdown%}
|
17
|
+
{{ sig.documentation }}
|
18
|
+
{%endmarkdown%}
|
19
|
+
{%endif%}</div>
|
20
|
+
<div class="last-signal-value" ng-show="signals['{{sig_name|lowerCamelCase}}']"></div>
|
21
|
+
</div>
|
22
|
+
{%endfor%}
|
23
|
+
{%raw%}
|
24
|
+
<div id="console" ng-class="{ 'expanded' : (console.showing) }">
|
25
|
+
<div class="top" ng-click=" console.showing = !console.showing ">Request Console <span ng-show="console.showing && console.requests.length > 0" ng-click="console.requests = []"> - Clear</span>
|
26
|
+
<p class="expanded-toggle">{{ console.showing ? 'Hide' : 'Show' }}</p>
|
27
|
+
</div>
|
28
|
+
<div id="request-list">
|
29
|
+
<p ng-repeat="msg in console.requests" class="entry">
|
30
|
+
<strong>{{msg.name}}:</strong> <em>{{msg.topic}}</em> <span class="elapsedTime" ng-show="msg.responseTime">{{msg.responseTime - msg.requestTime}}ms</span><span class="elapsedTime" ng-show="msg.eventTime">{{msg.eventTime}}</span>
|
31
|
+
<span class="outgoing" ng-show="msg.payload">{{msg.payload}}</span>
|
32
|
+
<span class="incoming" ng-show="msg.response">{{msg.response}}</span>
|
33
|
+
<span ng-repeat="result in msg.results" class="action-result">{{result}}</span>
|
34
|
+
</p>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
{%endraw%}
|
38
|
+
|
39
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
|
40
|
+
<script src="https://unpkg.com/mqtt@5.14.0/dist/mqtt.min.js"></script>
|
41
|
+
<script src="app.js"></script>
|
42
|
+
</body>
|
43
|
+
</html>
|
@@ -0,0 +1,187 @@
|
|
1
|
+
{%raw%}
|
2
|
+
@charset "UTF-8";
|
3
|
+
@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700");
|
4
|
+
|
5
|
+
body {
|
6
|
+
font-family: "Open Sans", sans-serif;
|
7
|
+
}
|
8
|
+
|
9
|
+
.clickable:hover {
|
10
|
+
text-decoration: underline;
|
11
|
+
color: blue;
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
.modeoption {
|
16
|
+
margin: 5px;
|
17
|
+
}
|
18
|
+
|
19
|
+
.pending {
|
20
|
+
color: #aaa;
|
21
|
+
animation: color-transition 1s ease-in-out infinite alternate;
|
22
|
+
}
|
23
|
+
|
24
|
+
@keyframes color-transition {
|
25
|
+
from {
|
26
|
+
color: #aaa;
|
27
|
+
}
|
28
|
+
to {
|
29
|
+
color: #eee;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
.actioning {
|
34
|
+
animation: shadow-transition 1s ease-in-out infinite alternate;
|
35
|
+
}
|
36
|
+
|
37
|
+
@keyframes shadow-transition {
|
38
|
+
from {
|
39
|
+
text-shadow: 0px 0px 10px #aaaaaa15;
|
40
|
+
}
|
41
|
+
to {
|
42
|
+
text-shadow: 0px 0px 10px #eee;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
.infobox-background {
|
47
|
+
position: fixed; /* Stay in place */
|
48
|
+
z-index: 1; /* Sit on top */
|
49
|
+
padding-top: 100px; /* Location of the box */
|
50
|
+
left: 0;
|
51
|
+
top: 0;
|
52
|
+
width: 100%; /* Full width */
|
53
|
+
height: 100%; /* Full height */
|
54
|
+
overflow: auto; /* Enable scroll if needed */
|
55
|
+
background-color: rgb(0,0,0); /* Fallback color */
|
56
|
+
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
57
|
+
}
|
58
|
+
|
59
|
+
.infobox-content {
|
60
|
+
background-color: #fefefe;
|
61
|
+
margin: auto;
|
62
|
+
padding: 20px;
|
63
|
+
border: 1px solid #888;
|
64
|
+
width: 80%;
|
65
|
+
top: 10%;
|
66
|
+
z-index: 2;
|
67
|
+
position: fixed;
|
68
|
+
overflow-y: scroll;
|
69
|
+
max-height: 80%;
|
70
|
+
}
|
71
|
+
|
72
|
+
.infobox-close {
|
73
|
+
color: #aaaaaa;
|
74
|
+
float: right;
|
75
|
+
font-size: 28px;
|
76
|
+
font-weight: bold;
|
77
|
+
}
|
78
|
+
|
79
|
+
.infobox-close:hover, .infobox-close:focus {
|
80
|
+
color: #000;
|
81
|
+
text-decoration: none;
|
82
|
+
cursor: pointer;
|
83
|
+
}
|
84
|
+
|
85
|
+
.infobox-device-refresh {
|
86
|
+
float: right;
|
87
|
+
font-size: 28px;
|
88
|
+
}
|
89
|
+
|
90
|
+
#offline {
|
91
|
+
height: 100vh;
|
92
|
+
display: flex;
|
93
|
+
justify-content: center;
|
94
|
+
font-size: 48px;
|
95
|
+
color: white;
|
96
|
+
}
|
97
|
+
|
98
|
+
#refresh-buttons {
|
99
|
+
position: fixed;
|
100
|
+
right: 10px;
|
101
|
+
z-index: 1;
|
102
|
+
}
|
103
|
+
|
104
|
+
#refresh-buttons p {
|
105
|
+
margin-top: 0;
|
106
|
+
}
|
107
|
+
|
108
|
+
#console {
|
109
|
+
border: 1px solid black;
|
110
|
+
background-color:rgba(179, 179, 179, 0.54);
|
111
|
+
bottom: 0;
|
112
|
+
left: 0;
|
113
|
+
width: 40%;
|
114
|
+
height: 1.5em;
|
115
|
+
position: fixed;
|
116
|
+
}
|
117
|
+
|
118
|
+
#console.expanded {
|
119
|
+
height: 40%;
|
120
|
+
}
|
121
|
+
|
122
|
+
#console .top {
|
123
|
+
background-color: rgba(43, 43, 43, 0.397);
|
124
|
+
top: 0;
|
125
|
+
width: 100%;
|
126
|
+
position: absolute;
|
127
|
+
height: 1.5em;
|
128
|
+
}
|
129
|
+
|
130
|
+
#console .top .expanded-toggle {
|
131
|
+
display: block;
|
132
|
+
right: 1em;
|
133
|
+
top: -.7em;
|
134
|
+
position:absolute;
|
135
|
+
}
|
136
|
+
|
137
|
+
#request-list {
|
138
|
+
margin-top: 2em;
|
139
|
+
}
|
140
|
+
|
141
|
+
#request-list .entry {
|
142
|
+
border-bottom: 1px black dashed;
|
143
|
+
}
|
144
|
+
|
145
|
+
#request-list .entry em {
|
146
|
+
font-size: 6pt;
|
147
|
+
overflow-wrap: anywhere;
|
148
|
+
display: block;
|
149
|
+
opacity: 0.8;
|
150
|
+
}
|
151
|
+
|
152
|
+
#request-list .entry .elapsedTime {
|
153
|
+
float: right;
|
154
|
+
position: relative;
|
155
|
+
top: -2.2em;
|
156
|
+
right: 1em;
|
157
|
+
font-size: 10pt;
|
158
|
+
color: rgba(49, 49, 102, 0.795);
|
159
|
+
}
|
160
|
+
|
161
|
+
#request-list .entry .outgoing, #request-list .entry .incoming, #request-list .entry .action-result {
|
162
|
+
font-family: 'Andale Mono', 'Courier New', Courier, monospace;
|
163
|
+
font-size: 9pt;
|
164
|
+
overflow-wrap: anywhere;
|
165
|
+
display: block;
|
166
|
+
}
|
167
|
+
|
168
|
+
#request-list .entry .outgoing::before {
|
169
|
+
content: "➡";
|
170
|
+
}
|
171
|
+
|
172
|
+
#request-list .entry .incoming::before {
|
173
|
+
content: "⬅";
|
174
|
+
}
|
175
|
+
|
176
|
+
#request-list .entry .action-result::before {
|
177
|
+
content: "✪";
|
178
|
+
}
|
179
|
+
|
180
|
+
.sched-table tr td, .sched-table tr th {
|
181
|
+
border: 1px solid #aaa;
|
182
|
+
}
|
183
|
+
|
184
|
+
td input.ng-invalid.ng-dirty {
|
185
|
+
background-color: rgb(255, 152, 152);
|
186
|
+
}
|
187
|
+
{%endraw%}
|
@@ -1,12 +1,11 @@
|
|
1
1
|
[package]
|
2
|
-
name = "{{stinger.
|
2
|
+
name = "{{stinger.rust.client_package_name}}"
|
3
3
|
version = "{{stinger.version}}"
|
4
4
|
edition = "2024"
|
5
5
|
|
6
|
-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
7
|
-
|
8
6
|
[dependencies]
|
9
|
-
|
7
|
+
mqttier = { git = "https://github.com/stinger-ipc/mqttier.git" }
|
8
|
+
{{stinger.rust.common_package_name}} = { path = "../payloads" }
|
10
9
|
futures = "0.3"
|
11
10
|
json = "0.12.4"
|
12
11
|
paho-mqtt = "0.13.3"
|
@@ -22,4 +21,7 @@ features = [
|
|
22
21
|
"v4", # Lets you generate random UUIDs
|
23
22
|
"fast-rng", # Use a faster (but still sufficiently random) RNG
|
24
23
|
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
|
25
|
-
]
|
24
|
+
]
|
25
|
+
[[example]]
|
26
|
+
name = "{{stinger.name | snake_case}}_client_demo"
|
27
|
+
path = "examples/client.rs"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
use futures::{executor::block_on};
|
2
|
-
use
|
3
|
-
use
|
2
|
+
use mqttier::MqttierClient;
|
3
|
+
use {{stinger.rust.client_package_name}}::{{stinger.rust.client_struct_name}};
|
4
4
|
use tokio::time::{sleep, Duration};
|
5
5
|
use tokio::join;
|
6
6
|
|
@@ -8,16 +8,17 @@ use tokio::join;
|
|
8
8
|
async fn main() {
|
9
9
|
block_on(async {
|
10
10
|
{%set broker = stinger.get_example_broker()%}
|
11
|
-
let mut
|
12
|
-
let mut
|
11
|
+
let mut mqttier_client = MqttierClient::new("localhost", 1883, Some("client_example".to_string())).unwrap();
|
12
|
+
let {%if stinger.methods|length > 0%}mut {%endif%}api_client = {{stinger.rust.client_struct_name}}::new(&mut mqttier_client).await;
|
13
13
|
|
14
|
+
let client_for_loop = api_client.clone();
|
14
15
|
tokio::spawn(async move {
|
15
16
|
println!("Making call to start connection loop");
|
16
|
-
let _conn_loop =
|
17
|
+
let _conn_loop = client_for_loop.run_loop().await;
|
17
18
|
});
|
18
19
|
|
19
20
|
{%for sig_name, sig in stinger.signals.items()%}
|
20
|
-
let mut sig_rx =
|
21
|
+
let mut sig_rx = api_client.get_{{sig_name|snake_case}}_receiver();
|
21
22
|
println!("Got signal receiver for {{sig_name}}");
|
22
23
|
|
23
24
|
sleep(Duration::from_secs(5)).await;
|
@@ -38,16 +39,14 @@ async fn main() {
|
|
38
39
|
});
|
39
40
|
{%endfor%}
|
40
41
|
|
41
|
-
println!("Starting client receive loop");
|
42
|
-
let _client_loop = client.receive_loop().await;
|
43
42
|
|
44
43
|
{%for method_name, method in stinger.methods.items()%}
|
45
44
|
println!("Calling {{method_name}} with example values...");
|
46
|
-
let result =
|
45
|
+
let result = api_client.{{method_name | snake_case}}({%for arg in method.arg_list%}{{arg.get_random_example_value(lang='rust')}}{%if not loop.last%}, {%endif%}{%endfor%}).await.expect("Failed to call {{method_name}}");
|
47
46
|
println!("{{method_name}} response: {:?}", result);
|
48
47
|
{%endfor%}
|
49
48
|
|
50
|
-
join!(sig_rx_task);
|
49
|
+
let _ = join!(sig_rx_task);
|
51
50
|
});
|
52
51
|
// Ctrl-C to stop
|
53
52
|
}
|