stinger-ipc 0.0.4__py3-none-any.whl → 0.0.7__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.
Files changed (29) hide show
  1. {stinger_ipc-0.0.4.dist-info → stinger_ipc-0.0.7.dist-info}/METADATA +3 -2
  2. {stinger_ipc-0.0.4.dist-info → stinger_ipc-0.0.7.dist-info}/RECORD +27 -23
  3. stinger_ipc-0.0.7.dist-info/entry_points.txt +5 -0
  4. stingeripc/components.py +5 -5
  5. stingeripc/lang_symb.py +21 -4
  6. stingeripc/templates/html/app.js.jinja2 +117 -0
  7. stingeripc/templates/html/index.html.jinja2 +38 -0
  8. stingeripc/templates/html/style.css.jinja2 +187 -0
  9. stingeripc/templates/rust/Cargo.toml.jinja2 +1 -1
  10. stingeripc/templates/rust/client/Cargo.toml.jinja2 +7 -5
  11. stingeripc/templates/rust/client/examples/client.rs.jinja2 +9 -10
  12. stingeripc/templates/rust/client/src/lib.rs.jinja2 +112 -55
  13. stingeripc/templates/rust/{connection → payloads}/Cargo.toml.jinja2 +8 -4
  14. stingeripc/templates/rust/{connection → payloads}/examples/pub_and_recv.rs.jinja2 +11 -11
  15. stingeripc/templates/rust/payloads/src/lib.rs.jinja2 +4 -0
  16. stingeripc/templates/rust/{connection → payloads}/src/payloads.rs.jinja2 +10 -2
  17. stingeripc/templates/rust/server/Cargo.toml.jinja2 +4 -4
  18. stingeripc/templates/rust/server/examples/server.rs.jinja2 +8 -12
  19. stingeripc/templates/rust/server/src/lib.rs.jinja2 +92 -69
  20. stingeripc/tools/cli.py +73 -0
  21. stingeripc/tools/markdown_generator.py +16 -7
  22. stingeripc/tools/python_generator.py +23 -11
  23. stingeripc/tools/rust_generator.py +46 -27
  24. stinger_ipc-0.0.4.dist-info/entry_points.txt +0 -4
  25. stingeripc/templates/rust/connection/src/lib.rs.jinja2 +0 -262
  26. {stinger_ipc-0.0.4.dist-info → stinger_ipc-0.0.7.dist-info}/WHEEL +0 -0
  27. {stinger_ipc-0.0.4.dist-info → stinger_ipc-0.0.7.dist-info}/licenses/LICENSE +0 -0
  28. {stinger_ipc-0.0.4.dist-info → stinger_ipc-0.0.7.dist-info}/top_level.txt +0 -0
  29. /stingeripc/templates/rust/{connection → payloads}/src/handler.rs.jinja2 +0 -0
@@ -1,16 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stinger-ipc
3
- Version: 0.0.4
3
+ Version: 0.0.7
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
12
12
  Requires-Dist: ruamel-yaml>=0.18.14
13
13
  Requires-Dist: stringcase>=1.2.0
14
+ Requires-Dist: typer>=0.16.1
14
15
  Requires-Dist: yamlloader>=1.5.1
15
16
  Dynamic: license-file
16
17
 
@@ -1,12 +1,12 @@
1
- stinger_ipc-0.0.4.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
1
+ stinger_ipc-0.0.7.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=WtIfhKAm9ZglCZiW-k98vAUC1Y5j3BJtcNRdMgr44zQ,38536
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=STcGEQQd72RK4J9UZr_vQgjVqf7dR9UZ2f9qicxjxGo,2736
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=UQkCYkGQpbiwd8MN7F3V6q6ruBPjRkJNnf9Glo3s0sE,3990
26
+ stingeripc/templates/html/index.html.jinja2,sha256=xBx0PYWnkRG1ttz53SQACDyMCFN5noUpTR3ECEzkc1I,2050
27
+ stingeripc/templates/html/style.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=lj9sCbw5-mJ4dz8-naEsc3xOlpgW6rdAxasuDjmag6M,72
34
- stingeripc/templates/rust/client/Cargo.toml.jinja2,sha256=2996MNw2YVxQuneuQBNypQzgig1W5rS915LahM1jFl8,743
35
- stingeripc/templates/rust/client/examples/client.rs.jinja2,sha256=xBrIwHJOrMjxFI-nUBejvI52JxgBBQ52KVzLK_ONyVM,2070
36
- stingeripc/templates/rust/client/src/lib.rs.jinja2,sha256=CQIXAhwTeU1pNSJhdD9mxmQOoaoKIwW2VNykryOeRJs,12756
37
- stingeripc/templates/rust/connection/Cargo.toml.jinja2,sha256=-DkDvR7q6l5SNsl9fcvDS05wXGGag9jv3tsXd4xmOuQ,553
38
- stingeripc/templates/rust/connection/examples/pub_and_recv.rs.jinja2,sha256=dD0HnFdXqpMYQK8u-37hl1c24dtrg6vbGVjWEjZA-1k,1513
39
- stingeripc/templates/rust/connection/src/handler.rs.jinja2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- stingeripc/templates/rust/connection/src/lib.rs.jinja2,sha256=00J0gOg3MZZIejFzay2ELCZZSiR_i0hsuF7ZQXk0lWE,10062
41
- stingeripc/templates/rust/connection/src/payloads.rs.jinja2,sha256=rlQgHeiCYGU8yq2fKlt9-khVfwvZdVjQNHOmLuzZznI,4130
42
- stingeripc/templates/rust/server/Cargo.toml.jinja2,sha256=eyMM4xmZP-9mlDJMQ5zrFR1dWWmoldMac6h_aFKtPQs,476
43
- stingeripc/templates/rust/server/examples/server.rs.jinja2,sha256=6XrMXUrcr9c0_m5u02kQzM88UHngVcUQCqL5uChefS8,3682
44
- stingeripc/templates/rust/server/src/lib.rs.jinja2,sha256=CFIrHI9LkZ2P1vX-YOOa0TwVVzqnVo59RnDAIXYV5Iw,13580
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/markdown_generator.py,sha256=C-Xjz1B8HSXiScj-f9aDYkvXG7TueRz5Ft9sL4P85k8,631
47
- stingeripc/tools/python_generator.py,sha256=hdmowp4xquoy9QGVkAsnYMfs30pnjVAf7O_v7BnM2Bc,1232
48
- stingeripc/tools/rust_generator.py,sha256=cjl7kbTT92FXpZlZdlq_R3F7lPxcMMOxGQjP9wH1nvo,1824
49
- stinger_ipc-0.0.4.dist-info/METADATA,sha256=5J-i0dZQdoL1dLyJBW2TtFt4-1VjVSLpaU01iDTv7bg,6008
50
- stinger_ipc-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
- stinger_ipc-0.0.4.dist-info/entry_points.txt,sha256=OP6HFi6z11HE_zxLsy9kPnoq8C2anF--_NiHMsMcazY,171
52
- stinger_ipc-0.0.4.dist-info/top_level.txt,sha256=mSNwAf83_1qiTP_vu7XEPBrZu-fDusT1FFyQZzCrRcU,11
53
- stinger_ipc-0.0.4.dist-info/RECORD,,
49
+ stingeripc/tools/cli.py,sha256=oLfVQx4EqRgZ2AH9Xl7X6neXle-aJE55bSXTEvH7RDE,2303
50
+ stingeripc/tools/markdown_generator.py,sha256=hvLbltMLQRG2Gy8l_44GUeDlT5P1eBoSjiEv6HMGrR8,1170
51
+ stingeripc/tools/python_generator.py,sha256=GJwGI6DntkJPJjHN4xSeTD60KgY32gI43IvIByxWSsw,1845
52
+ stingeripc/tools/rust_generator.py,sha256=9E7SMDM-iHE3O26QI3ieAHIInlrLepWMAFRnflKk3KI,2235
53
+ stinger_ipc-0.0.7.dist-info/METADATA,sha256=ogXMAU8avU-vkG2uV7h5PIkRxhroOjFuuwsvYqZY3N4,6037
54
+ stinger_ipc-0.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
55
+ stinger_ipc-0.0.7.dist-info/entry_points.txt,sha256=bh8k8mvtAog4MKTd82ALSHqQkuD069VrZ-vNlde6XjE,204
56
+ stinger_ipc-0.0.7.dist-info/top_level.txt,sha256=mSNwAf83_1qiTP_vu7XEPBrZu-fDusT1FFyQZzCrRcU,11
57
+ stinger_ipc-0.0.7.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ markdowngen = stingeripc.tools.markdown_generator:run
3
+ pythongen = stingeripc.tools.python_generator:run
4
+ rustgen = stingeripc.tools.rust_generator:main
5
+ stinger = stingeripc.tools.cli:run
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(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:
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,117 @@
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.data = {
26
+ "signals": [{%for _ in stinger.signals.keys()%} null{%if not loop.last%}, {%endif%}{%endfor%}],
27
+ "properties": [{%for _ in stinger.properties.keys()%} null{%if not loop.last%}, {%endif%}{%endfor%}],
28
+ }
29
+
30
+ $scope.console = {
31
+ showing: false,
32
+ requests: []
33
+ }
34
+
35
+ $scope.showoutput = false;
36
+ $scope.linuxoutput = '';
37
+
38
+ const brokerUrl = 'ws://' + location.hostname + ':' + location.port + '/ws'
39
+
40
+ const connectOptions = {
41
+ keepAlive: 60,
42
+ clientId: clientId,
43
+ protocolId: 'MQTT',
44
+ protocolVersion: 5,
45
+ clean: true
46
+ };
47
+
48
+ var client = mqtt.connect(brokerUrl, connectOptions);
49
+
50
+ client.on('close', function() {
51
+ console.log("Connection Lost");
52
+ });
53
+
54
+ function publish(name, topic, payload, qos) {
55
+ console.log(name + " Sending to " + topic);
56
+ console.log(payload);
57
+ let props = makeRequestProperties();
58
+ props
59
+ $scope.console.requests.unshift({"name":name, "correlationData":props.correlationData, "topic": topic, "payload": payload, "response": null, "requestTime": Date.now()});
60
+ client.publish(topic, payload, { "qos": qos, retain: false, properties: props});
61
+ return props.correlationData;
62
+ }
63
+
64
+ client.on('message', function(topic, message, packet) {
65
+ console.log("Message Arrived: " + topic);
66
+
67
+ const subid = packet.properties.subscriptionIdentifier;
68
+
69
+ if (subid >= signalSubIdStart && subid < propertySubIdStart) {
70
+ const signal_index = subid - signalSubIdStart;
71
+ console.log("Signal index: " + signal_index);
72
+ $scope.data.signals[signal_index] = JSON.parse(message.toString());
73
+ } else if (subid >= propertySubIdStart && subid < propertySubIdStart + {{stinger.properties|length}}) {
74
+ const prop_index = subid - propertySubIdStart;
75
+ console.log("Property index: " + prop_index);
76
+ $scope.data.properties[prop_index] = JSON.parse(message.toString());
77
+ }
78
+
79
+ var obj;
80
+ if (message.toString().length == 0) {
81
+ obj = null;
82
+ } else {
83
+ obj = JSON.parse(message.toString());
84
+ }
85
+ console.log(obj);
86
+
87
+ $scope.$apply();
88
+ });
89
+
90
+ client.on('connect', function() {
91
+ console.log("Connected with ", client);
92
+ {%for signal_name, signal in stinger.signals.items() %}
93
+ const {{sig_name}}_sub_opts = {
94
+ "qos": 1,
95
+ "properties": {
96
+ "subscriptionIdentifier": (signalSubIdStart + {{loop.index}})
97
+ }
98
+ };
99
+ client.subscribe("{{signal.topic}}", {{sig_name}}_sub_opts);
100
+ console.log("Subscribing to {{signal.topic}} with id {{loop.index}}");
101
+ {%endfor%}
102
+ {%for prop_name, prop in stinger.properties.items() %}
103
+ const {{prop_name}}_sub_opts = {
104
+ "qos": 1,
105
+ "properties": {
106
+ "subscriptionIdentifier": (propertySubIdStart + {{loop.index}})
107
+ }
108
+ };
109
+ client.subscribe("{{prop.value_topic}}", {{prop_name}}_sub_opts);
110
+ console.log("Subscribing to {{prop.value_topic}} with id {{loop.index + stinger.signals|length}}");
111
+ {%endfor%}
112
+ subscription_state = 1;
113
+ $scope.$apply();
114
+ });
115
+
116
+
117
+ });
@@ -0,0 +1,38 @@
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
+ <p class="signal-doc">{{ sig.documentation }}</p>
16
+ <div class="last-signal-value" ng-show="signals[{{loop.index}}]"></div>
17
+ </div>
18
+ {%endfor%}
19
+
20
+ <div id="console" ng-class="{ 'expanded' : (console.showing) }">
21
+ <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>
22
+ <p class="expanded-toggle">{{ console.showing ? 'Hide' : 'Show' }}</p>
23
+ </div>
24
+ <div id="request-list">
25
+ <p ng-repeat="msg in console.requests" class="entry">
26
+ {% raw %}<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>{%endraw%}
27
+ <span class="outgoing" ng-show="msg.payload">{{msg.payload}}</span>
28
+ <span class="incoming" ng-show="msg.response">{{msg.response}}</span>
29
+ <span ng-repeat="result in msg.results" class="action-result">{{result}}</span>
30
+ </p>
31
+ </div>
32
+ </div>
33
+
34
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
35
+ <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
36
+ <script src="app2.js"></script>
37
+ </body>
38
+ </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,4 +1,4 @@
1
1
  [workspace]
2
- members = ["server", "client", "connection"]
2
+ members = ["server", "client", "payloads"]
3
3
 
4
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
  }