@uns-kit/cli 0.0.34 → 0.0.36
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.
- package/LICENSE +21 -21
- package/README.md +128 -128
- package/dist/index.js +181 -6
- package/package.json +2 -2
- package/templates/api/src/examples/api-example.ts +62 -61
- package/templates/azure-pipelines.yml +21 -21
- package/templates/codegen/codegen.ts +15 -15
- package/templates/codegen/src/uns/uns-tags.ts +1 -1
- package/templates/codegen/src/uns/uns-topics.ts +1 -1
- package/templates/config-files/config-docker.json +27 -0
- package/templates/config-files/config-localhost.json +27 -0
- package/templates/cron/src/examples/cron-example.ts +46 -45
- package/templates/default/README.md +30 -30
- package/templates/default/config.json +27 -27
- package/templates/default/gitignore +51 -48
- package/templates/default/package.json +19 -19
- package/templates/default/src/config/project.config.extension.example +23 -23
- package/templates/default/src/config/project.config.extension.ts +6 -6
- package/templates/default/src/examples/data-example.ts +68 -68
- package/templates/default/src/examples/load-test-data.ts +108 -108
- package/templates/default/src/examples/table-example.ts +66 -66
- package/templates/default/src/examples/uns-gateway-cli.ts +7 -7
- package/templates/default/src/index.ts +15 -15
- package/templates/default/src/uns/uns-tags.ts +2 -2
- package/templates/default/src/uns/uns-topics.ts +2 -2
- package/templates/default/tsconfig.json +16 -16
- package/templates/python/app/README.md +8 -0
- package/templates/python/app/__init__.py +0 -0
- package/templates/python/examples/README.md +134 -84
- package/templates/python/examples/__init__.py +0 -0
- package/templates/python/examples/api_handler.py +28 -101
- package/templates/python/examples/data_publish.py +11 -0
- package/templates/python/examples/data_subscribe.py +8 -124
- package/templates/python/examples/data_transformer.py +17 -147
- package/templates/python/examples/table_transformer.py +16 -163
- package/templates/python/gateway/__init__.py +0 -0
- package/templates/python/gateway/cli.py +75 -0
- package/templates/python/gateway/client.py +155 -0
- package/templates/python/gateway/manager.py +97 -0
- package/templates/python/gen/__init__.py +1 -0
- package/templates/python/gen/uns_gateway_pb2.py +70 -0
- package/templates/python/gen/uns_gateway_pb2_grpc.py +312 -0
- package/templates/python/main.py +1 -0
- package/templates/python/proto/uns-gateway.proto +102 -102
- package/templates/python/pyproject.toml +5 -0
- package/templates/python/scripts/setup.sh +87 -64
- package/templates/temporal/src/examples/temporal-example.ts +35 -34
- package/templates/vscode/.vscode/launch.json +164 -164
- package/templates/vscode/.vscode/settings.json +9 -9
- package/templates/vscode/uns-kit.code-workspace +13 -13
- package/templates/python/examples/api_register_and_serve.py +0 -159
- package/templates/python/examples/data_publish_once.py +0 -140
- package/templates/python/examples/data_publisher_loop.py +0 -142
- package/templates/python/gateway_client.py +0 -242
- package/templates/python/local/README.md +0 -8
- package/templates/python/local/__init__.py +0 -2
- package/templates/python/requirements.txt +0 -3
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from . import uns_gateway_pb2 as uns__gateway__pb2
|
|
7
|
+
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.75.1'
|
|
9
|
+
GRPC_VERSION = grpc.__version__
|
|
10
|
+
_version_not_supported = False
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from grpc._utilities import first_version_is_lower
|
|
14
|
+
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
|
|
15
|
+
except ImportError:
|
|
16
|
+
_version_not_supported = True
|
|
17
|
+
|
|
18
|
+
if _version_not_supported:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
f'The grpc package installed is at version {GRPC_VERSION},'
|
|
21
|
+
+ f' but the generated code in uns_gateway_pb2_grpc.py depends on'
|
|
22
|
+
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
|
|
23
|
+
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
|
|
24
|
+
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class UnsGatewayStub(object):
|
|
29
|
+
"""Missing associated documentation comment in .proto file."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, channel):
|
|
32
|
+
"""Constructor.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
channel: A grpc.Channel.
|
|
36
|
+
"""
|
|
37
|
+
self.Publish = channel.unary_unary(
|
|
38
|
+
'/uns.UnsGateway/Publish',
|
|
39
|
+
request_serializer=uns__gateway__pb2.PublishRequest.SerializeToString,
|
|
40
|
+
response_deserializer=uns__gateway__pb2.Ack.FromString,
|
|
41
|
+
_registered_method=True)
|
|
42
|
+
self.Subscribe = channel.unary_stream(
|
|
43
|
+
'/uns.UnsGateway/Subscribe',
|
|
44
|
+
request_serializer=uns__gateway__pb2.SubscribeRequest.SerializeToString,
|
|
45
|
+
response_deserializer=uns__gateway__pb2.MqttMessage.FromString,
|
|
46
|
+
_registered_method=True)
|
|
47
|
+
self.RegisterApiGet = channel.unary_unary(
|
|
48
|
+
'/uns.UnsGateway/RegisterApiGet',
|
|
49
|
+
request_serializer=uns__gateway__pb2.RegisterApiGetRequest.SerializeToString,
|
|
50
|
+
response_deserializer=uns__gateway__pb2.Ack.FromString,
|
|
51
|
+
_registered_method=True)
|
|
52
|
+
self.UnregisterApiGet = channel.unary_unary(
|
|
53
|
+
'/uns.UnsGateway/UnregisterApiGet',
|
|
54
|
+
request_serializer=uns__gateway__pb2.UnregisterApiGetRequest.SerializeToString,
|
|
55
|
+
response_deserializer=uns__gateway__pb2.Ack.FromString,
|
|
56
|
+
_registered_method=True)
|
|
57
|
+
self.ApiEventStream = channel.stream_stream(
|
|
58
|
+
'/uns.UnsGateway/ApiEventStream',
|
|
59
|
+
request_serializer=uns__gateway__pb2.ApiEventResponse.SerializeToString,
|
|
60
|
+
response_deserializer=uns__gateway__pb2.ApiEvent.FromString,
|
|
61
|
+
_registered_method=True)
|
|
62
|
+
self.Ready = channel.unary_unary(
|
|
63
|
+
'/uns.UnsGateway/Ready',
|
|
64
|
+
request_serializer=uns__gateway__pb2.ReadyRequest.SerializeToString,
|
|
65
|
+
response_deserializer=uns__gateway__pb2.Ack.FromString,
|
|
66
|
+
_registered_method=True)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class UnsGatewayServicer(object):
|
|
70
|
+
"""Missing associated documentation comment in .proto file."""
|
|
71
|
+
|
|
72
|
+
def Publish(self, request, context):
|
|
73
|
+
"""Missing associated documentation comment in .proto file."""
|
|
74
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
75
|
+
context.set_details('Method not implemented!')
|
|
76
|
+
raise NotImplementedError('Method not implemented!')
|
|
77
|
+
|
|
78
|
+
def Subscribe(self, request, context):
|
|
79
|
+
"""Missing associated documentation comment in .proto file."""
|
|
80
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
81
|
+
context.set_details('Method not implemented!')
|
|
82
|
+
raise NotImplementedError('Method not implemented!')
|
|
83
|
+
|
|
84
|
+
def RegisterApiGet(self, request, context):
|
|
85
|
+
"""Missing associated documentation comment in .proto file."""
|
|
86
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
87
|
+
context.set_details('Method not implemented!')
|
|
88
|
+
raise NotImplementedError('Method not implemented!')
|
|
89
|
+
|
|
90
|
+
def UnregisterApiGet(self, request, context):
|
|
91
|
+
"""Missing associated documentation comment in .proto file."""
|
|
92
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
93
|
+
context.set_details('Method not implemented!')
|
|
94
|
+
raise NotImplementedError('Method not implemented!')
|
|
95
|
+
|
|
96
|
+
def ApiEventStream(self, request_iterator, context):
|
|
97
|
+
"""Missing associated documentation comment in .proto file."""
|
|
98
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
99
|
+
context.set_details('Method not implemented!')
|
|
100
|
+
raise NotImplementedError('Method not implemented!')
|
|
101
|
+
|
|
102
|
+
def Ready(self, request, context):
|
|
103
|
+
"""Missing associated documentation comment in .proto file."""
|
|
104
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
105
|
+
context.set_details('Method not implemented!')
|
|
106
|
+
raise NotImplementedError('Method not implemented!')
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def add_UnsGatewayServicer_to_server(servicer, server):
|
|
110
|
+
rpc_method_handlers = {
|
|
111
|
+
'Publish': grpc.unary_unary_rpc_method_handler(
|
|
112
|
+
servicer.Publish,
|
|
113
|
+
request_deserializer=uns__gateway__pb2.PublishRequest.FromString,
|
|
114
|
+
response_serializer=uns__gateway__pb2.Ack.SerializeToString,
|
|
115
|
+
),
|
|
116
|
+
'Subscribe': grpc.unary_stream_rpc_method_handler(
|
|
117
|
+
servicer.Subscribe,
|
|
118
|
+
request_deserializer=uns__gateway__pb2.SubscribeRequest.FromString,
|
|
119
|
+
response_serializer=uns__gateway__pb2.MqttMessage.SerializeToString,
|
|
120
|
+
),
|
|
121
|
+
'RegisterApiGet': grpc.unary_unary_rpc_method_handler(
|
|
122
|
+
servicer.RegisterApiGet,
|
|
123
|
+
request_deserializer=uns__gateway__pb2.RegisterApiGetRequest.FromString,
|
|
124
|
+
response_serializer=uns__gateway__pb2.Ack.SerializeToString,
|
|
125
|
+
),
|
|
126
|
+
'UnregisterApiGet': grpc.unary_unary_rpc_method_handler(
|
|
127
|
+
servicer.UnregisterApiGet,
|
|
128
|
+
request_deserializer=uns__gateway__pb2.UnregisterApiGetRequest.FromString,
|
|
129
|
+
response_serializer=uns__gateway__pb2.Ack.SerializeToString,
|
|
130
|
+
),
|
|
131
|
+
'ApiEventStream': grpc.stream_stream_rpc_method_handler(
|
|
132
|
+
servicer.ApiEventStream,
|
|
133
|
+
request_deserializer=uns__gateway__pb2.ApiEventResponse.FromString,
|
|
134
|
+
response_serializer=uns__gateway__pb2.ApiEvent.SerializeToString,
|
|
135
|
+
),
|
|
136
|
+
'Ready': grpc.unary_unary_rpc_method_handler(
|
|
137
|
+
servicer.Ready,
|
|
138
|
+
request_deserializer=uns__gateway__pb2.ReadyRequest.FromString,
|
|
139
|
+
response_serializer=uns__gateway__pb2.Ack.SerializeToString,
|
|
140
|
+
),
|
|
141
|
+
}
|
|
142
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
143
|
+
'uns.UnsGateway', rpc_method_handlers)
|
|
144
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
145
|
+
server.add_registered_method_handlers('uns.UnsGateway', rpc_method_handlers)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# This class is part of an EXPERIMENTAL API.
|
|
149
|
+
class UnsGateway(object):
|
|
150
|
+
"""Missing associated documentation comment in .proto file."""
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def Publish(request,
|
|
154
|
+
target,
|
|
155
|
+
options=(),
|
|
156
|
+
channel_credentials=None,
|
|
157
|
+
call_credentials=None,
|
|
158
|
+
insecure=False,
|
|
159
|
+
compression=None,
|
|
160
|
+
wait_for_ready=None,
|
|
161
|
+
timeout=None,
|
|
162
|
+
metadata=None):
|
|
163
|
+
return grpc.experimental.unary_unary(
|
|
164
|
+
request,
|
|
165
|
+
target,
|
|
166
|
+
'/uns.UnsGateway/Publish',
|
|
167
|
+
uns__gateway__pb2.PublishRequest.SerializeToString,
|
|
168
|
+
uns__gateway__pb2.Ack.FromString,
|
|
169
|
+
options,
|
|
170
|
+
channel_credentials,
|
|
171
|
+
insecure,
|
|
172
|
+
call_credentials,
|
|
173
|
+
compression,
|
|
174
|
+
wait_for_ready,
|
|
175
|
+
timeout,
|
|
176
|
+
metadata,
|
|
177
|
+
_registered_method=True)
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def Subscribe(request,
|
|
181
|
+
target,
|
|
182
|
+
options=(),
|
|
183
|
+
channel_credentials=None,
|
|
184
|
+
call_credentials=None,
|
|
185
|
+
insecure=False,
|
|
186
|
+
compression=None,
|
|
187
|
+
wait_for_ready=None,
|
|
188
|
+
timeout=None,
|
|
189
|
+
metadata=None):
|
|
190
|
+
return grpc.experimental.unary_stream(
|
|
191
|
+
request,
|
|
192
|
+
target,
|
|
193
|
+
'/uns.UnsGateway/Subscribe',
|
|
194
|
+
uns__gateway__pb2.SubscribeRequest.SerializeToString,
|
|
195
|
+
uns__gateway__pb2.MqttMessage.FromString,
|
|
196
|
+
options,
|
|
197
|
+
channel_credentials,
|
|
198
|
+
insecure,
|
|
199
|
+
call_credentials,
|
|
200
|
+
compression,
|
|
201
|
+
wait_for_ready,
|
|
202
|
+
timeout,
|
|
203
|
+
metadata,
|
|
204
|
+
_registered_method=True)
|
|
205
|
+
|
|
206
|
+
@staticmethod
|
|
207
|
+
def RegisterApiGet(request,
|
|
208
|
+
target,
|
|
209
|
+
options=(),
|
|
210
|
+
channel_credentials=None,
|
|
211
|
+
call_credentials=None,
|
|
212
|
+
insecure=False,
|
|
213
|
+
compression=None,
|
|
214
|
+
wait_for_ready=None,
|
|
215
|
+
timeout=None,
|
|
216
|
+
metadata=None):
|
|
217
|
+
return grpc.experimental.unary_unary(
|
|
218
|
+
request,
|
|
219
|
+
target,
|
|
220
|
+
'/uns.UnsGateway/RegisterApiGet',
|
|
221
|
+
uns__gateway__pb2.RegisterApiGetRequest.SerializeToString,
|
|
222
|
+
uns__gateway__pb2.Ack.FromString,
|
|
223
|
+
options,
|
|
224
|
+
channel_credentials,
|
|
225
|
+
insecure,
|
|
226
|
+
call_credentials,
|
|
227
|
+
compression,
|
|
228
|
+
wait_for_ready,
|
|
229
|
+
timeout,
|
|
230
|
+
metadata,
|
|
231
|
+
_registered_method=True)
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
def UnregisterApiGet(request,
|
|
235
|
+
target,
|
|
236
|
+
options=(),
|
|
237
|
+
channel_credentials=None,
|
|
238
|
+
call_credentials=None,
|
|
239
|
+
insecure=False,
|
|
240
|
+
compression=None,
|
|
241
|
+
wait_for_ready=None,
|
|
242
|
+
timeout=None,
|
|
243
|
+
metadata=None):
|
|
244
|
+
return grpc.experimental.unary_unary(
|
|
245
|
+
request,
|
|
246
|
+
target,
|
|
247
|
+
'/uns.UnsGateway/UnregisterApiGet',
|
|
248
|
+
uns__gateway__pb2.UnregisterApiGetRequest.SerializeToString,
|
|
249
|
+
uns__gateway__pb2.Ack.FromString,
|
|
250
|
+
options,
|
|
251
|
+
channel_credentials,
|
|
252
|
+
insecure,
|
|
253
|
+
call_credentials,
|
|
254
|
+
compression,
|
|
255
|
+
wait_for_ready,
|
|
256
|
+
timeout,
|
|
257
|
+
metadata,
|
|
258
|
+
_registered_method=True)
|
|
259
|
+
|
|
260
|
+
@staticmethod
|
|
261
|
+
def ApiEventStream(request_iterator,
|
|
262
|
+
target,
|
|
263
|
+
options=(),
|
|
264
|
+
channel_credentials=None,
|
|
265
|
+
call_credentials=None,
|
|
266
|
+
insecure=False,
|
|
267
|
+
compression=None,
|
|
268
|
+
wait_for_ready=None,
|
|
269
|
+
timeout=None,
|
|
270
|
+
metadata=None):
|
|
271
|
+
return grpc.experimental.stream_stream(
|
|
272
|
+
request_iterator,
|
|
273
|
+
target,
|
|
274
|
+
'/uns.UnsGateway/ApiEventStream',
|
|
275
|
+
uns__gateway__pb2.ApiEventResponse.SerializeToString,
|
|
276
|
+
uns__gateway__pb2.ApiEvent.FromString,
|
|
277
|
+
options,
|
|
278
|
+
channel_credentials,
|
|
279
|
+
insecure,
|
|
280
|
+
call_credentials,
|
|
281
|
+
compression,
|
|
282
|
+
wait_for_ready,
|
|
283
|
+
timeout,
|
|
284
|
+
metadata,
|
|
285
|
+
_registered_method=True)
|
|
286
|
+
|
|
287
|
+
@staticmethod
|
|
288
|
+
def Ready(request,
|
|
289
|
+
target,
|
|
290
|
+
options=(),
|
|
291
|
+
channel_credentials=None,
|
|
292
|
+
call_credentials=None,
|
|
293
|
+
insecure=False,
|
|
294
|
+
compression=None,
|
|
295
|
+
wait_for_ready=None,
|
|
296
|
+
timeout=None,
|
|
297
|
+
metadata=None):
|
|
298
|
+
return grpc.experimental.unary_unary(
|
|
299
|
+
request,
|
|
300
|
+
target,
|
|
301
|
+
'/uns.UnsGateway/Ready',
|
|
302
|
+
uns__gateway__pb2.ReadyRequest.SerializeToString,
|
|
303
|
+
uns__gateway__pb2.Ack.FromString,
|
|
304
|
+
options,
|
|
305
|
+
channel_credentials,
|
|
306
|
+
insecure,
|
|
307
|
+
call_credentials,
|
|
308
|
+
compression,
|
|
309
|
+
wait_for_ready,
|
|
310
|
+
timeout,
|
|
311
|
+
metadata,
|
|
312
|
+
_registered_method=True)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"Main Logic"
|
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
|
|
3
|
-
package uns;
|
|
4
|
-
|
|
5
|
-
service UnsGateway {
|
|
6
|
-
rpc Publish (PublishRequest) returns (Ack);
|
|
7
|
-
rpc Subscribe (SubscribeRequest) returns (stream MqttMessage);
|
|
8
|
-
rpc RegisterApiGet (RegisterApiGetRequest) returns (Ack);
|
|
9
|
-
rpc UnregisterApiGet (UnregisterApiGetRequest) returns (Ack);
|
|
10
|
-
rpc ApiEventStream (stream ApiEventResponse) returns (stream ApiEvent);
|
|
11
|
-
rpc Ready (ReadyRequest) returns (Ack);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
message PublishRequest {
|
|
15
|
-
string topic = 1;
|
|
16
|
-
string attribute = 2;
|
|
17
|
-
string description = 3;
|
|
18
|
-
repeated string tags = 4;
|
|
19
|
-
bool attribute_needs_persistence = 5;
|
|
20
|
-
oneof content {
|
|
21
|
-
Data data = 6;
|
|
22
|
-
Table table = 7;
|
|
23
|
-
}
|
|
24
|
-
bool value_is_cumulative = 8; // for Data: publish as delta
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
message Data {
|
|
28
|
-
string time = 1;
|
|
29
|
-
double value_number = 2;
|
|
30
|
-
string value_string = 3;
|
|
31
|
-
string uom = 4;
|
|
32
|
-
string data_group = 5;
|
|
33
|
-
string foreign_event_key = 6;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
message TableValue {
|
|
37
|
-
string key = 1;
|
|
38
|
-
double value_number = 2;
|
|
39
|
-
string value_string = 3;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
message Table {
|
|
43
|
-
string time = 1;
|
|
44
|
-
repeated TableValue values = 2;
|
|
45
|
-
string data_group = 3;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
message SubscribeRequest {
|
|
49
|
-
repeated string topics = 1;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
message MqttMessage {
|
|
53
|
-
string topic = 1;
|
|
54
|
-
string payload = 2; // UNS packet JSON
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
message Ack {
|
|
58
|
-
bool ok = 1;
|
|
59
|
-
string error = 2;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
message ReadyRequest {
|
|
63
|
-
int32 timeout_ms = 1; // default 15000
|
|
64
|
-
bool wait_output = 2; // wait for publisher active (output)
|
|
65
|
-
bool wait_input = 3; // wait for subscriber active (input)
|
|
66
|
-
bool wait_api = 4; // wait for API server (optional)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
message ApiQueryParam {
|
|
70
|
-
string name = 1;
|
|
71
|
-
string type = 2; // string | number | boolean
|
|
72
|
-
bool required = 3;
|
|
73
|
-
string description = 4;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
message RegisterApiGetRequest {
|
|
77
|
-
string topic = 1;
|
|
78
|
-
string attribute = 2;
|
|
79
|
-
string api_description = 3;
|
|
80
|
-
repeated string tags = 4;
|
|
81
|
-
repeated ApiQueryParam query_params = 5;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
message UnregisterApiGetRequest {
|
|
85
|
-
string topic = 1;
|
|
86
|
-
string attribute = 2;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
message ApiEvent {
|
|
90
|
-
string id = 1;
|
|
91
|
-
string method = 2; // GET only for now
|
|
92
|
-
string path = 3; // /{topic}{attribute}
|
|
93
|
-
map<string, string> query = 4;
|
|
94
|
-
string bearer = 5; // access token (optional)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
message ApiEventResponse {
|
|
98
|
-
string id = 1; // correlation
|
|
99
|
-
int32 status = 2; // HTTP status
|
|
100
|
-
string body = 3; // response body as string (JSON string if needed)
|
|
101
|
-
map<string, string> headers = 4; // optional extra headers
|
|
102
|
-
}
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package uns;
|
|
4
|
+
|
|
5
|
+
service UnsGateway {
|
|
6
|
+
rpc Publish (PublishRequest) returns (Ack);
|
|
7
|
+
rpc Subscribe (SubscribeRequest) returns (stream MqttMessage);
|
|
8
|
+
rpc RegisterApiGet (RegisterApiGetRequest) returns (Ack);
|
|
9
|
+
rpc UnregisterApiGet (UnregisterApiGetRequest) returns (Ack);
|
|
10
|
+
rpc ApiEventStream (stream ApiEventResponse) returns (stream ApiEvent);
|
|
11
|
+
rpc Ready (ReadyRequest) returns (Ack);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
message PublishRequest {
|
|
15
|
+
string topic = 1;
|
|
16
|
+
string attribute = 2;
|
|
17
|
+
string description = 3;
|
|
18
|
+
repeated string tags = 4;
|
|
19
|
+
bool attribute_needs_persistence = 5;
|
|
20
|
+
oneof content {
|
|
21
|
+
Data data = 6;
|
|
22
|
+
Table table = 7;
|
|
23
|
+
}
|
|
24
|
+
bool value_is_cumulative = 8; // for Data: publish as delta
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
message Data {
|
|
28
|
+
string time = 1;
|
|
29
|
+
double value_number = 2;
|
|
30
|
+
string value_string = 3;
|
|
31
|
+
string uom = 4;
|
|
32
|
+
string data_group = 5;
|
|
33
|
+
string foreign_event_key = 6;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
message TableValue {
|
|
37
|
+
string key = 1;
|
|
38
|
+
double value_number = 2;
|
|
39
|
+
string value_string = 3;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
message Table {
|
|
43
|
+
string time = 1;
|
|
44
|
+
repeated TableValue values = 2;
|
|
45
|
+
string data_group = 3;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
message SubscribeRequest {
|
|
49
|
+
repeated string topics = 1;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
message MqttMessage {
|
|
53
|
+
string topic = 1;
|
|
54
|
+
string payload = 2; // UNS packet JSON
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
message Ack {
|
|
58
|
+
bool ok = 1;
|
|
59
|
+
string error = 2;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
message ReadyRequest {
|
|
63
|
+
int32 timeout_ms = 1; // default 15000
|
|
64
|
+
bool wait_output = 2; // wait for publisher active (output)
|
|
65
|
+
bool wait_input = 3; // wait for subscriber active (input)
|
|
66
|
+
bool wait_api = 4; // wait for API server (optional)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
message ApiQueryParam {
|
|
70
|
+
string name = 1;
|
|
71
|
+
string type = 2; // string | number | boolean
|
|
72
|
+
bool required = 3;
|
|
73
|
+
string description = 4;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
message RegisterApiGetRequest {
|
|
77
|
+
string topic = 1;
|
|
78
|
+
string attribute = 2;
|
|
79
|
+
string api_description = 3;
|
|
80
|
+
repeated string tags = 4;
|
|
81
|
+
repeated ApiQueryParam query_params = 5;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
message UnregisterApiGetRequest {
|
|
85
|
+
string topic = 1;
|
|
86
|
+
string attribute = 2;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
message ApiEvent {
|
|
90
|
+
string id = 1;
|
|
91
|
+
string method = 2; // GET only for now
|
|
92
|
+
string path = 3; // /{topic}{attribute}
|
|
93
|
+
map<string, string> query = 4;
|
|
94
|
+
string bearer = 5; // access token (optional)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
message ApiEventResponse {
|
|
98
|
+
string id = 1; // correlation
|
|
99
|
+
int32 status = 2; // HTTP status
|
|
100
|
+
string body = 3; // response body as string (JSON string if needed)
|
|
101
|
+
map<string, string> headers = 4; // optional extra headers
|
|
102
|
+
}
|
|
@@ -1,64 +1,87 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
# Navigate to the project root
|
|
6
|
-
cd "$(dirname "$0")/.."
|
|
7
|
-
|
|
8
|
-
# Detect OS and set
|
|
9
|
-
PLATFORM="$(uname)"
|
|
10
|
-
if [[ "$PLATFORM" == "Linux" || "$PLATFORM" == "Darwin" ]]; then
|
|
11
|
-
PYTHON_EXEC="python3"
|
|
12
|
-
VENV_DIR="venv"
|
|
13
|
-
VENV_ACTIVATE="./venv/bin/activate"
|
|
14
|
-
elif [[ "$PLATFORM" =~ MINGW.* || "$PLATFORM" =~ CYGWIN.* || "$PLATFORM" == "MSYS_NT"* ]]; then
|
|
15
|
-
PYTHON_EXEC="python"
|
|
16
|
-
VENV_DIR="venv"
|
|
17
|
-
VENV_ACTIVATE="./venv/Scripts/activate"
|
|
18
|
-
else
|
|
19
|
-
echo "[setup] Unsupported OS: $PLATFORM"
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
echo "
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"$
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
# Navigate to the project root
|
|
6
|
+
cd "$(dirname "$0")/.."
|
|
7
|
+
|
|
8
|
+
# Detect OS and set paths
|
|
9
|
+
PLATFORM="$(uname)"
|
|
10
|
+
if [[ "$PLATFORM" == "Linux" || "$PLATFORM" == "Darwin" ]]; then
|
|
11
|
+
PYTHON_EXEC="python3"
|
|
12
|
+
VENV_DIR="venv"
|
|
13
|
+
VENV_ACTIVATE="./venv/bin/activate"
|
|
14
|
+
elif [[ "$PLATFORM" =~ MINGW.* || "$PLATFORM" =~ CYGWIN.* || "$PLATFORM" == "MSYS_NT"* ]]; then
|
|
15
|
+
PYTHON_EXEC="python"
|
|
16
|
+
VENV_DIR="venv"
|
|
17
|
+
VENV_ACTIVATE="./venv/Scripts/activate"
|
|
18
|
+
else
|
|
19
|
+
echo "[setup] Unsupported OS: $PLATFORM"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
if [[ "$PLATFORM" =~ MINGW.*|MSYS.*|CYGWIN.*|Windows_NT ]]; then
|
|
24
|
+
UV_CMD="$HOME/.local/bin/uv.exe"
|
|
25
|
+
else
|
|
26
|
+
UV_CMD="$HOME/.cargo/bin/uv"
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if [ ! -f "$UV_CMD" ]; then
|
|
30
|
+
echo "[setup] uv not found. Installing it..."
|
|
31
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
32
|
+
else
|
|
33
|
+
echo "[setup] uv already installed at $UV_CMD"
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Create virtual environment using uv
|
|
37
|
+
if [ ! -d "$VENV_DIR" ]; then
|
|
38
|
+
echo "[setup] Creating virtual environment in $VENV_DIR using uv..."
|
|
39
|
+
"$UV_CMD" venv "$VENV_DIR"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Create gen directory if it doesn't exist
|
|
43
|
+
if [ ! -d "gen" ]; then
|
|
44
|
+
echo "[setup] Creating gen directory..."
|
|
45
|
+
mkdir -p gen
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Ensure gen is a package for imports
|
|
49
|
+
if [ ! -f "gen/__init__.py" ]; then
|
|
50
|
+
echo "[setup] Creating gen/__init__.py..."
|
|
51
|
+
echo "# generated" > gen/__init__.py
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Activate the virtual environment
|
|
55
|
+
echo "[setup] Activating virtual environment..."
|
|
56
|
+
if [[ "$PLATFORM" =~ MINGW.*|MSYS.*|CYGWIN.* ]]; then
|
|
57
|
+
# Windows Git Bash / MSYS
|
|
58
|
+
. "$VENV_ACTIVATE"
|
|
59
|
+
else
|
|
60
|
+
# Linux / macOS
|
|
61
|
+
source "$VENV_ACTIVATE"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Install dependencies using uv (much faster than pip)
|
|
65
|
+
echo "[setup] Installing requirements using uv..."
|
|
66
|
+
"$UV_CMD" sync --active
|
|
67
|
+
|
|
68
|
+
# Generate Python gRPC code from proto
|
|
69
|
+
echo "[setup] Generating gRPC Python code..."
|
|
70
|
+
"$PYTHON_EXEC" -m grpc_tools.protoc \
|
|
71
|
+
-I=proto \
|
|
72
|
+
--python_out=gen \
|
|
73
|
+
--grpc_python_out=gen \
|
|
74
|
+
proto/uns-gateway.proto
|
|
75
|
+
|
|
76
|
+
# Patch the generated _pb2_grpc.py to use relative imports
|
|
77
|
+
GRPC_FILE="gen/uns_gateway_pb2_grpc.py"
|
|
78
|
+
if [[ -f "$GRPC_FILE" ]]; then
|
|
79
|
+
echo "[setup] Patching $GRPC_FILE to use relative imports..."
|
|
80
|
+
if [[ "$PLATFORM" == "Linux" || "$PLATFORM" == "Darwin" ]]; then
|
|
81
|
+
sed -i 's/^import \(.*_pb2\) as/from . import \1 as/' "$GRPC_FILE"
|
|
82
|
+
elif [[ "$PLATFORM" =~ MINGW.*|MSYS.*|CYGWIN.* ]]; then
|
|
83
|
+
sed -i'' 's/^import \(.*_pb2\) as/from . import \1 as/' "$GRPC_FILE"
|
|
84
|
+
fi
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
echo "[setup] Setup complete!"
|