stinger-ipc 0.0.5__tar.gz → 0.0.8__tar.gz

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.
Files changed (71) hide show
  1. {stinger_ipc-0.0.5/stinger_ipc.egg-info → stinger_ipc-0.0.8}/PKG-INFO +2 -2
  2. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/pyproject.toml +3 -2
  3. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8/stinger_ipc.egg-info}/PKG-INFO +2 -2
  4. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stinger_ipc.egg-info/SOURCES.txt +9 -5
  5. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stinger_ipc.egg-info/entry_points.txt +1 -0
  6. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stinger_ipc.egg-info/requires.txt +1 -1
  7. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/components.py +5 -5
  8. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/lang_symb.py +21 -4
  9. stinger_ipc-0.0.8/stingeripc/templates/html/app.js.jinja2 +125 -0
  10. stinger_ipc-0.0.8/stingeripc/templates/html/index.html.jinja2 +43 -0
  11. stinger_ipc-0.0.8/stingeripc/templates/html/styles.css.jinja2 +187 -0
  12. stinger_ipc-0.0.8/stingeripc/templates/rust/Cargo.toml.jinja2 +4 -0
  13. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/rust/client/Cargo.toml.jinja2 +7 -5
  14. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/rust/client/examples/client.rs.jinja2 +9 -10
  15. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/rust/client/src/lib.rs.jinja2 +112 -55
  16. {stinger_ipc-0.0.5/stingeripc/templates/rust/connection → stinger_ipc-0.0.8/stingeripc/templates/rust/payloads}/Cargo.toml.jinja2 +8 -4
  17. {stinger_ipc-0.0.5/stingeripc/templates/rust/connection → stinger_ipc-0.0.8/stingeripc/templates/rust/payloads}/examples/pub_and_recv.rs.jinja2 +11 -11
  18. stinger_ipc-0.0.8/stingeripc/templates/rust/payloads/src/lib.rs.jinja2 +4 -0
  19. {stinger_ipc-0.0.5/stingeripc/templates/rust/connection → stinger_ipc-0.0.8/stingeripc/templates/rust/payloads}/src/payloads.rs.jinja2 +10 -2
  20. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/rust/server/Cargo.toml.jinja2 +4 -4
  21. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/rust/server/examples/server.rs.jinja2 +8 -12
  22. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/rust/server/src/lib.rs.jinja2 +92 -69
  23. stinger_ipc-0.0.8/stingeripc/tools/cli.py +73 -0
  24. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/tools/markdown_generator.py +4 -2
  25. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/tools/python_generator.py +12 -10
  26. stinger_ipc-0.0.8/stingeripc/tools/rust_generator.py +69 -0
  27. stinger_ipc-0.0.5/stingeripc/templates/rust/Cargo.toml.jinja2 +0 -4
  28. stinger_ipc-0.0.5/stingeripc/templates/rust/connection/src/lib.rs.jinja2 +0 -262
  29. stinger_ipc-0.0.5/stingeripc/tools/rust_generator.py +0 -50
  30. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/LICENSE +0 -0
  31. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/README.md +0 -0
  32. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/setup.cfg +0 -0
  33. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stinger_ipc.egg-info/dependency_links.txt +0 -0
  34. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stinger_ipc.egg-info/top_level.txt +0 -0
  35. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/__init__.py +0 -0
  36. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/args.py +0 -0
  37. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/asyncapi.py +0 -0
  38. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/connection.py +0 -0
  39. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/exceptions.py +0 -0
  40. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/interface.py +0 -0
  41. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/CMakeLists.txt.jinja2 +0 -0
  42. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/examples/client_main.cpp.jinja2 +0 -0
  43. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/examples/server_main.cpp.jinja2 +0 -0
  44. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/broker.hpp.jinja2 +0 -0
  45. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/client.hpp.jinja2 +0 -0
  46. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/enums.hpp.jinja2 +0 -0
  47. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/ibrokerconnection.hpp.jinja2 +0 -0
  48. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/property_structs.hpp.jinja2 +0 -0
  49. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/return_types.hpp.jinja2 +0 -0
  50. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/server.hpp.jinja2 +0 -0
  51. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/include/structs.hpp.jinja2 +0 -0
  52. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/src/broker.cpp.jinja2 +0 -0
  53. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/src/client.cpp.jinja2 +0 -0
  54. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/cpp/src/server.cpp.jinja2 +0 -0
  55. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/markdown/index.md.jinja2 +0 -0
  56. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/__init__.py.jinja2 +0 -0
  57. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/client.py.jinja2 +0 -0
  58. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/connection.py.jinja2 +0 -0
  59. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/interface_types.py.jinja2 +0 -0
  60. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/method_codes.py.jinja2 +0 -0
  61. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/pyproject.toml.jinja2 +0 -0
  62. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/templates/python/server.py.jinja2 +0 -0
  63. {stinger_ipc-0.0.5/stingeripc/templates/rust/connection → stinger_ipc-0.0.8/stingeripc/templates/rust/payloads}/src/handler.rs.jinja2 +0 -0
  64. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/tools/__init__.py +0 -0
  65. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/stingeripc/topic.py +0 -0
  66. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/tests/test_args.py +0 -0
  67. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/tests/test_enum.py +0 -0
  68. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/tests/test_examples.py +0 -0
  69. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/tests/test_interface.py +0 -0
  70. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/tests/test_signal.py +0 -0
  71. {stinger_ipc-0.0.5 → stinger_ipc-0.0.8}/tests/test_topics.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stinger-ipc
3
- Version: 0.0.5
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.1.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,11 +1,11 @@
1
1
  [project]
2
2
  name = "stinger-ipc"
3
- version = "0.0.5"
3
+ version = "0.0.8"
4
4
  description = "Tools to create code to do IPC over MQTT"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
7
7
  dependencies = [
8
- "jacobs-jinja-too>=0.1.0",
8
+ "jacobs-jinja-too>=0.2.4",
9
9
  "packaging>=25.0",
10
10
  "pydantic>=2.11.7",
11
11
  "pyyaml>=6.0.2",
@@ -45,3 +45,4 @@ stingeripc = [
45
45
  pythongen = "stingeripc.tools.python_generator:run"
46
46
  rustgen = "stingeripc.tools.rust_generator:main"
47
47
  markdowngen = "stingeripc.tools.markdown_generator:run"
48
+ stinger = "stingeripc.tools.cli:run"
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stinger-ipc
3
- Version: 0.0.5
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.1.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
@@ -30,6 +30,9 @@ stingeripc/templates/cpp/include/structs.hpp.jinja2
30
30
  stingeripc/templates/cpp/src/broker.cpp.jinja2
31
31
  stingeripc/templates/cpp/src/client.cpp.jinja2
32
32
  stingeripc/templates/cpp/src/server.cpp.jinja2
33
+ stingeripc/templates/html/app.js.jinja2
34
+ stingeripc/templates/html/index.html.jinja2
35
+ stingeripc/templates/html/styles.css.jinja2
33
36
  stingeripc/templates/markdown/index.md.jinja2
34
37
  stingeripc/templates/python/__init__.py.jinja2
35
38
  stingeripc/templates/python/client.py.jinja2
@@ -42,15 +45,16 @@ stingeripc/templates/rust/Cargo.toml.jinja2
42
45
  stingeripc/templates/rust/client/Cargo.toml.jinja2
43
46
  stingeripc/templates/rust/client/examples/client.rs.jinja2
44
47
  stingeripc/templates/rust/client/src/lib.rs.jinja2
45
- stingeripc/templates/rust/connection/Cargo.toml.jinja2
46
- stingeripc/templates/rust/connection/examples/pub_and_recv.rs.jinja2
47
- stingeripc/templates/rust/connection/src/handler.rs.jinja2
48
- stingeripc/templates/rust/connection/src/lib.rs.jinja2
49
- stingeripc/templates/rust/connection/src/payloads.rs.jinja2
48
+ stingeripc/templates/rust/payloads/Cargo.toml.jinja2
49
+ stingeripc/templates/rust/payloads/examples/pub_and_recv.rs.jinja2
50
+ stingeripc/templates/rust/payloads/src/handler.rs.jinja2
51
+ stingeripc/templates/rust/payloads/src/lib.rs.jinja2
52
+ stingeripc/templates/rust/payloads/src/payloads.rs.jinja2
50
53
  stingeripc/templates/rust/server/Cargo.toml.jinja2
51
54
  stingeripc/templates/rust/server/examples/server.rs.jinja2
52
55
  stingeripc/templates/rust/server/src/lib.rs.jinja2
53
56
  stingeripc/tools/__init__.py
57
+ stingeripc/tools/cli.py
54
58
  stingeripc/tools/markdown_generator.py
55
59
  stingeripc/tools/python_generator.py
56
60
  stingeripc/tools/rust_generator.py
@@ -2,3 +2,4 @@
2
2
  markdowngen = stingeripc.tools.markdown_generator:run
3
3
  pythongen = stingeripc.tools.python_generator:run
4
4
  rustgen = stingeripc.tools.rust_generator:main
5
+ stinger = stingeripc.tools.cli:run
@@ -1,4 +1,4 @@
1
- jacobs-jinja-too>=0.1.0
1
+ jacobs-jinja-too>=0.2.4
2
2
  packaging>=25.0
3
3
  pydantic>=2.11.7
4
4
  pyyaml>=6.0.2
@@ -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(connection::payloads::{self._enum.class_name}::{stringmanip.upper_camel_case(value)})"
206
+ retval = f"Some({self._enum.class_name}::{stringmanip.upper_camel_case(value)})"
207
207
  else:
208
- retval = f"connection::payloads::{self._enum.class_name}::{stringmanip.upper_camel_case(value)}"
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"connection::payloads::{self.rust_local_type}"
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"connection::payloads::{self.rust_local_type}"
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"connection::payloads::{self.rust_local_type}"
814
+ return f"{self.rust_local_type}"
815
815
 
816
816
  @property
817
817
  def cpp_type(self) -> str:
@@ -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%}
@@ -0,0 +1,4 @@
1
+ [workspace]
2
+ members = ["server", "client", "payloads"]
3
+
4
+ resolver = "2"
@@ -1,12 +1,11 @@
1
1
  [package]
2
- name = "{{stinger.name | snake_case}}_client"
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
- connection = { path = "../connection" }
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 {{stinger.name | snake_case}}_client::{{stinger.rust.client_struct_name}};
3
- use connection::Connection;
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 connection = Connection::new_{{broker.class_name|snake_case}}().await.expect("Failed to create connection");
12
- let mut client = {{stinger.rust.client_struct_name}}::new(&mut connection).await;
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 = connection.start_loop().await;
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 = client.get_{{sig_name|snake_case}}_receiver();
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 = 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}}");
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
  }