fleetmqsdk 0.0.1__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.
- fleetmqsdk-0.0.1/PKG-INFO +16 -0
- fleetmqsdk-0.0.1/fleetmqsdk/Abc_config_pb2.py +60 -0
- fleetmqsdk-0.0.1/fleetmqsdk/Message_pb2.py +54 -0
- fleetmqsdk-0.0.1/fleetmqsdk/__init__.py +0 -0
- fleetmqsdk-0.0.1/fleetmqsdk/fleetmqsdk.py +249 -0
- fleetmqsdk-0.0.1/fleetmqsdk.egg-info/PKG-INFO +16 -0
- fleetmqsdk-0.0.1/fleetmqsdk.egg-info/SOURCES.txt +10 -0
- fleetmqsdk-0.0.1/fleetmqsdk.egg-info/dependency_links.txt +1 -0
- fleetmqsdk-0.0.1/fleetmqsdk.egg-info/requires.txt +3 -0
- fleetmqsdk-0.0.1/fleetmqsdk.egg-info/top_level.txt +1 -0
- fleetmqsdk-0.0.1/setup.cfg +4 -0
- fleetmqsdk-0.0.1/setup.py +19 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: fleetmqsdk
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A convenient SDK for FleetMQ
|
|
5
|
+
Author: Nicole
|
|
6
|
+
Author-email: nicole@fleetmq.io
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Requires-Dist: google-api-python-client
|
|
10
|
+
Requires-Dist: pyzmq
|
|
11
|
+
Requires-Dist: setuptools
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: author-email
|
|
14
|
+
Dynamic: classifier
|
|
15
|
+
Dynamic: requires-dist
|
|
16
|
+
Dynamic: summary
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: Abc_config.proto
|
|
4
|
+
# Protobuf Python Version: 5.26.1
|
|
5
|
+
"""Generated protocol buffer code."""
|
|
6
|
+
from google.protobuf import descriptor as _descriptor
|
|
7
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
8
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
9
|
+
from google.protobuf.internal import builder as _builder
|
|
10
|
+
# @@protoc_insertion_point(imports)
|
|
11
|
+
|
|
12
|
+
_sym_db = _symbol_database.Default()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10\x41\x62\x63_config.proto\x12\x0e\x61\x62\x63onnectproto\x1a\x1bgoogle/protobuf/empty.proto\"\xb6\x01\n\x0f\x41\x42\x43onnectConfig\x12\x10\n\x08group_id\x18\x03 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12=\n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32,.abconnectproto.ABConnectConfig.DevicesEntry\x1a\x46\n\x0c\x44\x65vicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.abconnectproto.Device:\x02\x38\x01\"\xba\x02\n\x06\x44\x65vice\x12;\n\x0bsend_topics\x18\x01 \x03(\x0b\x32&.abconnectproto.Device.SendTopicsEntry\x12\x41\n\x0ereceive_topics\x18\x02 \x03(\x0b\x32).abconnectproto.Device.ReceiveTopicsEntry\x12\x0e\n\x06joined\x18\x03 \x01(\x08\x1aL\n\x0fSendTopicsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12(\n\x05value\x18\x02 \x01(\x0b\x32\x19.abconnectproto.Publisher:\x02\x38\x01\x1aR\n\x12ReceiveTopicsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12+\n\x05value\x18\x02 \x01(\x0b\x32\x1c.abconnectproto.Subscription:\x02\x38\x01\"\x9f\x03\n\x06Source\x12\x31\n\x06source\x18\x01 \x01(\x0e\x32!.abconnectproto.Source.SourceType\x12\x10\n\x08zmq_port\x18\x04 \x01(\x05\x12\x1a\n\x12source_device_name\x18\x05 \x01(\t\x12\x13\n\x0bsource_file\x18\x06 \x01(\t\x12\x36\n\x0bvideo_codec\x18\x07 \x01(\x0e\x32!.abconnectproto.Source.VideoCodec\"\x8f\x01\n\nSourceType\x12\r\n\tUNDEFINED\x10\x00\x12\t\n\x05STDIN\x10\x01\x12\t\n\x05VIDEO\x10\x02\x12\r\n\tZMQ_VIDEO\x10\x03\x12\x0c\n\x08ROS_DATA\x10\x04\x12\r\n\tZMQ_AUDIO\x10\x05\x12\t\n\x05\x41UDIO\x10\x06\x12\x0b\n\x07MAVLINK\x10\x07\x12\x0e\n\nTIME_PROBE\x10\x08\x12\x08\n\x04\x46ILE\x10\t\"1\n\nVideoCodec\x12\x19\n\x15VIDEO_CODEC_UNDEFINED\x10\x00\x12\x08\n\x04MMAL\x10\x01J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04R\x08video_idR\x0cros_msg_type\"\xe9\x01\n\tPublisher\x12\r\n\x05topic\x18\x01 \x01(\t\x12&\n\x06source\x18\x03 \x01(\x0b\x32\x16.abconnectproto.Source\x12M\n\x13subscriber_peer_ids\x18\x04 \x03(\x0b\x32\x30.abconnectproto.Publisher.SubscriberPeerIdsEntry\x1aP\n\x16SubscriberPeerIdsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Empty:\x02\x38\x01J\x04\x08\x02\x10\x03\"\xf5\x01\n\x04Sink\x12+\n\x04sink\x18\x01 \x01(\x0e\x32\x1d.abconnectproto.Sink.SinkType\x12\x10\n\x08zmq_port\x18\x03 \x01(\x05\x12\x11\n\tsink_file\x18\x04 \x01(\t\"p\n\x08SinkType\x12\r\n\tUNDEFINED\x10\x00\x12\n\n\x06STDOUT\x10\x01\x12\x0c\n\x08ROS_DATA\x10\x02\x12\t\n\x05VIDEO\x10\x03\x12\t\n\x05\x41UDIO\x10\x04\x12\x0b\n\x07MAVLINK\x10\x05\x12\x0e\n\nTIME_PROBE\x10\x06\x12\x08\n\x04\x46ILE\x10\x07J\x04\x08\x02\x10\x03J\x04\x08\x05\x10\x06R\x0cros_msg_typeR\x0flocal_web_media\"\\\n\x0cSubscription\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x19\n\x11publisher_peer_id\x18\x02 \x01(\t\x12\"\n\x04sink\x18\x03 \x01(\x0b\x32\x14.abconnectproto.SinkB\x0cZ\n/messagepbb\x06proto3')
|
|
19
|
+
|
|
20
|
+
_globals = globals()
|
|
21
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
22
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'Abc_config_pb2', _globals)
|
|
23
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
24
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
25
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\n/messagepb'
|
|
26
|
+
_globals['_ABCONNECTCONFIG_DEVICESENTRY']._loaded_options = None
|
|
27
|
+
_globals['_ABCONNECTCONFIG_DEVICESENTRY']._serialized_options = b'8\001'
|
|
28
|
+
_globals['_DEVICE_SENDTOPICSENTRY']._loaded_options = None
|
|
29
|
+
_globals['_DEVICE_SENDTOPICSENTRY']._serialized_options = b'8\001'
|
|
30
|
+
_globals['_DEVICE_RECEIVETOPICSENTRY']._loaded_options = None
|
|
31
|
+
_globals['_DEVICE_RECEIVETOPICSENTRY']._serialized_options = b'8\001'
|
|
32
|
+
_globals['_PUBLISHER_SUBSCRIBERPEERIDSENTRY']._loaded_options = None
|
|
33
|
+
_globals['_PUBLISHER_SUBSCRIBERPEERIDSENTRY']._serialized_options = b'8\001'
|
|
34
|
+
_globals['_ABCONNECTCONFIG']._serialized_start=66
|
|
35
|
+
_globals['_ABCONNECTCONFIG']._serialized_end=248
|
|
36
|
+
_globals['_ABCONNECTCONFIG_DEVICESENTRY']._serialized_start=178
|
|
37
|
+
_globals['_ABCONNECTCONFIG_DEVICESENTRY']._serialized_end=248
|
|
38
|
+
_globals['_DEVICE']._serialized_start=251
|
|
39
|
+
_globals['_DEVICE']._serialized_end=565
|
|
40
|
+
_globals['_DEVICE_SENDTOPICSENTRY']._serialized_start=405
|
|
41
|
+
_globals['_DEVICE_SENDTOPICSENTRY']._serialized_end=481
|
|
42
|
+
_globals['_DEVICE_RECEIVETOPICSENTRY']._serialized_start=483
|
|
43
|
+
_globals['_DEVICE_RECEIVETOPICSENTRY']._serialized_end=565
|
|
44
|
+
_globals['_SOURCE']._serialized_start=568
|
|
45
|
+
_globals['_SOURCE']._serialized_end=983
|
|
46
|
+
_globals['_SOURCE_SOURCETYPE']._serialized_start=753
|
|
47
|
+
_globals['_SOURCE_SOURCETYPE']._serialized_end=896
|
|
48
|
+
_globals['_SOURCE_VIDEOCODEC']._serialized_start=898
|
|
49
|
+
_globals['_SOURCE_VIDEOCODEC']._serialized_end=947
|
|
50
|
+
_globals['_PUBLISHER']._serialized_start=986
|
|
51
|
+
_globals['_PUBLISHER']._serialized_end=1219
|
|
52
|
+
_globals['_PUBLISHER_SUBSCRIBERPEERIDSENTRY']._serialized_start=1133
|
|
53
|
+
_globals['_PUBLISHER_SUBSCRIBERPEERIDSENTRY']._serialized_end=1213
|
|
54
|
+
_globals['_SINK']._serialized_start=1222
|
|
55
|
+
_globals['_SINK']._serialized_end=1467
|
|
56
|
+
_globals['_SINK_SINKTYPE']._serialized_start=1312
|
|
57
|
+
_globals['_SINK_SINKTYPE']._serialized_end=1424
|
|
58
|
+
_globals['_SUBSCRIPTION']._serialized_start=1469
|
|
59
|
+
_globals['_SUBSCRIPTION']._serialized_end=1561
|
|
60
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: Message.proto
|
|
4
|
+
# Protobuf Python Version: 5.26.1
|
|
5
|
+
"""Generated protocol buffer code."""
|
|
6
|
+
from google.protobuf import descriptor as _descriptor
|
|
7
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
8
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
9
|
+
from google.protobuf.internal import builder as _builder
|
|
10
|
+
# @@protoc_insertion_point(imports)
|
|
11
|
+
|
|
12
|
+
_sym_db = _symbol_database.Default()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
import Abc_config_pb2 as Abc__config__pb2
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rMessage.proto\x12\x0e\x61\x62\x63onnectproto\x1a\x10\x41\x62\x63_config.proto\"\x9a\x04\n\x10\x41\x42\x43onnectMessage\x12&\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x15.abconnectproto.ErrorH\x00\x12\"\n\x03icm\x18\x01 \x01(\x0b\x32\x13.abconnectproto.ICMH\x00\x12.\n\tsignaling\x18\x02 \x01(\x0b\x32\x19.abconnectproto.SignalingH\x00\x12*\n\x02wf\x18\x03 \x01(\x0b\x32\x1c.abconnectproto.WebFrameworkH\x00\x12\x31\n\x06\x63onfig\x18\x07 \x01(\x0b\x32\x1f.abconnectproto.ABConnectConfigH\x00\x12\x37\n\x0e\x63onfig_request\x18\n \x01(\x0b\x32\x1d.abconnectproto.ConfigRequestH\x00\x12\x35\n\x10\x63reate_publisher\x18\x0b \x01(\x0b\x32\x19.abconnectproto.PublisherH\x00\x12;\n\x13\x63reate_subscription\x18\x0c \x01(\x0b\x32\x1c.abconnectproto.SubscriptionH\x00\x12/\n\rdevice_config\x18\r \x01(\x0b\x32\x16.abconnectproto.DeviceH\x00\x12\x0c\n\x04\x66rom\x18\x05 \x01(\t\x12\n\n\x02to\x18\x06 \x01(\t\x12\x11\n\tconfig_id\x18\x08 \x01(\t\x12\x10\n\x08group_id\x18\t \x01(\tB\x0e\n\x0cmessage_type\"\x92\x02\n\x03ICM\x12+\n\x05\x65vent\x18\x01 \x01(\x0e\x32\x1c.abconnectproto.ICM.ICMEvent\x12<\n\rmedia_sources\x18\x02 \x03(\x0b\x32%.abconnectproto.ICM.MediaSourcesEntry\x12\x0f\n\x07version\x18\x03 \x01(\t\x1aK\n\x11MediaSourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.abconnectproto.Source:\x02\x38\x01\"B\n\x08ICMEvent\x12\r\n\tUNDEFINED\x10\x00\x12\x08\n\x04JOIN\x10\x01\x12\t\n\x05LEAVE\x10\x02\x12\x08\n\x04PING\x10\x03\x12\x08\n\x04PONG\x10\x04\"\xe5\x03\n\tSignaling\x12\x36\n\x04type\x18\x01 \x01(\x0e\x32(.abconnectproto.Signaling.ConnectionType\x12=\n\rconnection_id\x18\x04 \x01(\x0e\x32&.abconnectproto.Signaling.ConnectionID\x12\x37\n\x05\x65vent\x18\x02 \x01(\x0e\x32(.abconnectproto.Signaling.SignalingEvent\x12\x0f\n\x07payload\x18\x03 \x01(\t\"[\n\x0e\x43onnectionType\x12\x1d\n\x19\x43ONNECTION_TYPE_UNDEFINED\x10\x00\x12\x11\n\rCONNECT_BY_ID\x10\x01\x12\x17\n\x13\x43ONNECT_BY_CATEGORY\x10\x02\"G\n\x0c\x43onnectionID\x12\x1b\n\x17\x43ONNECTION_ID_UNDEFINED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\"q\n\x0eSignalingEvent\x12\x1d\n\x19SIGNALING_EVENT_UNDEFINED\x10\x00\x12\x10\n\x0cOPEN_REQUEST\x10\x01\x12\x11\n\rOPEN_RESPONSE\x10\x02\x12\t\n\x05\x43LOSE\x10\x03\x12\x07\n\x03SDP\x10\x04\x12\x07\n\x03ICE\x10\x05\"\x94\x01\n\x0cWebFramework\x12=\n\x05\x65vent\x18\x01 \x01(\x0e\x32..abconnectproto.WebFramework.WebFrameworkEvent\x12\x0f\n\x07payload\x18\x02 \x01(\t\"4\n\x11WebFrameworkEvent\x12\r\n\tUNDEFINED\x10\x00\x12\x10\n\x0cGRAPH_UPDATE\x10\x01\"\xf4\x02\n\x05\x45rror\x12.\n\x05\x65rror\x18\x01 \x01(\x0e\x32\x1f.abconnectproto.Error.ErrorType\x12\x15\n\rerror_message\x18\x02 \x01(\t\"\xa3\x02\n\tErrorType\x12\r\n\tUNDEFINED\x10\x00\x12\x14\n\x10UNIQUENESS_ERROR\x10\x01\x12\x1a\n\x16\x44\x45VICE_NOT_FOUND_ERROR\x10\x02\x12\x1c\n\x18\x43\x41TEGORY_NOT_FOUND_ERROR\x10\x03\x12\x15\n\x11\x41LREADY_CONNECTED\x10\x04\x12\x12\n\x0eUNKNOWN_CONFIG\x10\x05\x12\x14\n\x10INCORRECT_CONFIG\x10\x08\x12\x11\n\rUNKNOWN_GROUP\x10\x07\x12\x13\n\x0fINVALID_MESSAGE\x10\x06\x12\x1a\n\x16\x43REATE_PUBLISHER_ERROR\x10\t\x12\x1d\n\x19\x43REATE_SUBSCRIPTION_ERROR\x10\n\x12\x13\n\x0fINVALID_VERSION\x10\x0b\"\x0f\n\rConfigRequestB\x0cZ\n/messagepbb\x06proto3')
|
|
19
|
+
|
|
20
|
+
_globals = globals()
|
|
21
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
22
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'Message_pb2', _globals)
|
|
23
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
24
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
25
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\n/messagepb'
|
|
26
|
+
_globals['_ICM_MEDIASOURCESENTRY']._loaded_options = None
|
|
27
|
+
_globals['_ICM_MEDIASOURCESENTRY']._serialized_options = b'8\001'
|
|
28
|
+
_globals['_ABCONNECTMESSAGE']._serialized_start=52
|
|
29
|
+
_globals['_ABCONNECTMESSAGE']._serialized_end=590
|
|
30
|
+
_globals['_ICM']._serialized_start=593
|
|
31
|
+
_globals['_ICM']._serialized_end=867
|
|
32
|
+
_globals['_ICM_MEDIASOURCESENTRY']._serialized_start=724
|
|
33
|
+
_globals['_ICM_MEDIASOURCESENTRY']._serialized_end=799
|
|
34
|
+
_globals['_ICM_ICMEVENT']._serialized_start=801
|
|
35
|
+
_globals['_ICM_ICMEVENT']._serialized_end=867
|
|
36
|
+
_globals['_SIGNALING']._serialized_start=870
|
|
37
|
+
_globals['_SIGNALING']._serialized_end=1355
|
|
38
|
+
_globals['_SIGNALING_CONNECTIONTYPE']._serialized_start=1076
|
|
39
|
+
_globals['_SIGNALING_CONNECTIONTYPE']._serialized_end=1167
|
|
40
|
+
_globals['_SIGNALING_CONNECTIONID']._serialized_start=1169
|
|
41
|
+
_globals['_SIGNALING_CONNECTIONID']._serialized_end=1240
|
|
42
|
+
_globals['_SIGNALING_SIGNALINGEVENT']._serialized_start=1242
|
|
43
|
+
_globals['_SIGNALING_SIGNALINGEVENT']._serialized_end=1355
|
|
44
|
+
_globals['_WEBFRAMEWORK']._serialized_start=1358
|
|
45
|
+
_globals['_WEBFRAMEWORK']._serialized_end=1506
|
|
46
|
+
_globals['_WEBFRAMEWORK_WEBFRAMEWORKEVENT']._serialized_start=1454
|
|
47
|
+
_globals['_WEBFRAMEWORK_WEBFRAMEWORKEVENT']._serialized_end=1506
|
|
48
|
+
_globals['_ERROR']._serialized_start=1509
|
|
49
|
+
_globals['_ERROR']._serialized_end=1881
|
|
50
|
+
_globals['_ERROR_ERRORTYPE']._serialized_start=1590
|
|
51
|
+
_globals['_ERROR_ERRORTYPE']._serialized_end=1881
|
|
52
|
+
_globals['_CONFIGREQUEST']._serialized_start=1883
|
|
53
|
+
_globals['_CONFIGREQUEST']._serialized_end=1898
|
|
54
|
+
# @@protoc_insertion_point(module_scope)
|
|
File without changes
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import Message_pb2
|
|
2
|
+
import zmq
|
|
3
|
+
|
|
4
|
+
tcpPrefix = "tcp://0.0.0.0:"
|
|
5
|
+
ipcPrefix = "ipc:///tmp/feeds/"
|
|
6
|
+
|
|
7
|
+
def _getAddress(port, ipc):
|
|
8
|
+
if ipc:
|
|
9
|
+
return ipcPrefix + port
|
|
10
|
+
else:
|
|
11
|
+
return tcpPrefix + port
|
|
12
|
+
|
|
13
|
+
class FleetMQ:
|
|
14
|
+
def __init__(self):
|
|
15
|
+
print("FleetMQ SDK")
|
|
16
|
+
self._context = zmq.Context()
|
|
17
|
+
self._rpcSocket = self._initRpcReq()
|
|
18
|
+
self._publishers = {}
|
|
19
|
+
self._subscribers = {}
|
|
20
|
+
|
|
21
|
+
def __enter__(self):
|
|
22
|
+
return self
|
|
23
|
+
|
|
24
|
+
def __exit__(self, type, value, traceback):
|
|
25
|
+
self.close()
|
|
26
|
+
|
|
27
|
+
def close(self):
|
|
28
|
+
self._rpcSocket.close()
|
|
29
|
+
for publisher in self._publishers.values():
|
|
30
|
+
publisher.close()
|
|
31
|
+
for subscriber in self._subscribers.values():
|
|
32
|
+
subscriber.close()
|
|
33
|
+
|
|
34
|
+
def _initRpcReq(self, rpcReqPort="5558"):
|
|
35
|
+
address = 'tcp://localhost:' + rpcReqPort
|
|
36
|
+
try:
|
|
37
|
+
rpcReqInterface = self._context.socket(zmq.REQ)
|
|
38
|
+
rpcReqInterface.connect(address)
|
|
39
|
+
print("Connected to RPC request address: " + address)
|
|
40
|
+
except zmq.ZMQError as e:
|
|
41
|
+
print(f"Failed to open RPC request socket on port {rpcReqPort}: {e}")
|
|
42
|
+
exit(1)
|
|
43
|
+
return rpcReqInterface
|
|
44
|
+
|
|
45
|
+
def _createPublisherFromConfig(self, port, topic, ipc=False):
|
|
46
|
+
if topic in self._publishers:
|
|
47
|
+
# Publisher already exists
|
|
48
|
+
print("Publisher for topic " + topic + " already exists")
|
|
49
|
+
return
|
|
50
|
+
self._publishers[topic] = _Publisher(self._context, port, topic, ipc)
|
|
51
|
+
|
|
52
|
+
def _createSubscriberFromConfig(self, port, topic, ipc=False):
|
|
53
|
+
if topic in self._subscribers:
|
|
54
|
+
# Subscriber already exists
|
|
55
|
+
print("Subscriber for topic " + topic + " already exists")
|
|
56
|
+
return
|
|
57
|
+
self._subscribers[topic] = _Subscriber(self._context, port, topic, ipc)
|
|
58
|
+
|
|
59
|
+
def _createConfigState(self, config, ports):
|
|
60
|
+
for topic in config.send_topics:
|
|
61
|
+
if topic not in ports:
|
|
62
|
+
print("Error: send topic " + topic + " not found in ports, won't create publisher")
|
|
63
|
+
continue
|
|
64
|
+
self._createPublisherFromConfig(ports[topic], topic, config.send_topics[topic].source.source)
|
|
65
|
+
for topic in config.receive_topics:
|
|
66
|
+
if topic not in ports:
|
|
67
|
+
print("Error: receive topic " + topic + " not found in ports, won't create subscriber")
|
|
68
|
+
continue
|
|
69
|
+
self._createSubscriberFromConfig(ports[topic], topic, config.receive_topics[topic].sink.sink)
|
|
70
|
+
|
|
71
|
+
def _receiveConfig(self):
|
|
72
|
+
try:
|
|
73
|
+
configBytes = self._rpcSocket.recv_multipart()
|
|
74
|
+
if len(configBytes) != 2:
|
|
75
|
+
print("Error getting config from datastreamer, expected 2 frames, got " + str(len(configBytes)))
|
|
76
|
+
return None, None
|
|
77
|
+
|
|
78
|
+
# Parse received config data into ABConnectMessage.
|
|
79
|
+
msg = Message_pb2.ABConnectMessage()
|
|
80
|
+
msg.ParseFromString(configBytes[0])
|
|
81
|
+
|
|
82
|
+
# Evaluate the message type.
|
|
83
|
+
if msg.HasField("device_config"):
|
|
84
|
+
print("Received config response from datastreamer")
|
|
85
|
+
elif msg.HasField("error"):
|
|
86
|
+
print("Received Error from datastreamer: " + msg.error.error_message)
|
|
87
|
+
return None, None
|
|
88
|
+
else:
|
|
89
|
+
print("Unexpected message type received from datastreamer: " + msg)
|
|
90
|
+
exit(1)
|
|
91
|
+
|
|
92
|
+
except zmq.ZMQError as e:
|
|
93
|
+
print(f"Failed to receive config: {e}")
|
|
94
|
+
exit(1)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
portsString = configBytes[1].decode()
|
|
98
|
+
print("Ports: " + portsString)
|
|
99
|
+
|
|
100
|
+
print("Device config:")
|
|
101
|
+
print(msg.device_config)
|
|
102
|
+
|
|
103
|
+
return msg.device_config, eval(portsString)
|
|
104
|
+
|
|
105
|
+
def getConfig(self, createConfigState=False):
|
|
106
|
+
req = Message_pb2.ABConnectMessage()
|
|
107
|
+
req.config_request.SetInParent()
|
|
108
|
+
print("Sending config request to datastreamer...")
|
|
109
|
+
try:
|
|
110
|
+
self._rpcSocket.send(req.SerializeToString())
|
|
111
|
+
except zmq.ZMQError as e:
|
|
112
|
+
print(f"Failed to receive config: {e}")
|
|
113
|
+
exit(1)
|
|
114
|
+
|
|
115
|
+
# Wait for response
|
|
116
|
+
config, addresses = self._receiveConfig()
|
|
117
|
+
if config is None or addresses is None:
|
|
118
|
+
print("Failed to get config from datastreamer")
|
|
119
|
+
exit(1)
|
|
120
|
+
|
|
121
|
+
if createConfigState:
|
|
122
|
+
self._createConfigState(config, addresses)
|
|
123
|
+
|
|
124
|
+
return config, addresses
|
|
125
|
+
|
|
126
|
+
# CreatePublisher creates a publisher for the given topic, executing an rpc to the datastreamer
|
|
127
|
+
# to provision a zmq port.
|
|
128
|
+
def createPublisher(self, topic, source_type):
|
|
129
|
+
if topic in self._publishers:
|
|
130
|
+
# Publisher already exists
|
|
131
|
+
print("Publisher for topic " + topic + " already exists")
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
req = Message_pb2.ABConnectMessage()
|
|
135
|
+
req.create_publisher.topic = topic
|
|
136
|
+
req.create_publisher.source.source = source_type
|
|
137
|
+
print("Sending create publisher request to datastreamer...")
|
|
138
|
+
try:
|
|
139
|
+
self._rpcSocket.send(req.SerializeToString())
|
|
140
|
+
except zmq.ZMQError as e:
|
|
141
|
+
print(f"Failed to send CreatePublisher request to datastreamer: {e}")
|
|
142
|
+
exit(1)
|
|
143
|
+
|
|
144
|
+
config, ports = self._receiveConfig()
|
|
145
|
+
if config is None or ports is None:
|
|
146
|
+
print("Failed to create publisher")
|
|
147
|
+
exit(1)
|
|
148
|
+
self._createConfigState(config, ports)
|
|
149
|
+
|
|
150
|
+
if topic not in self._publishers:
|
|
151
|
+
print("Internal error, publisher for topic " + topic + " not created")
|
|
152
|
+
exit(1)
|
|
153
|
+
|
|
154
|
+
# CreateSubscriber creates a subscriber for the given topic, executing an rpc to the
|
|
155
|
+
# datastreamer to provision a zmq port.
|
|
156
|
+
def createSubscriber(self, topic, sink_type):
|
|
157
|
+
if topic in self._subscribers:
|
|
158
|
+
# Subscriber already exists
|
|
159
|
+
print("Subscriber for topic " + topic + " already exists")
|
|
160
|
+
return
|
|
161
|
+
|
|
162
|
+
req = Message_pb2.ABConnectMessage()
|
|
163
|
+
req.create_subscription.topic = topic
|
|
164
|
+
req.create_subscription.sink.sink = sink_type
|
|
165
|
+
print("Sending create subscriber request to datastreamer...")
|
|
166
|
+
try:
|
|
167
|
+
self._rpcSocket.send(req.SerializeToString())
|
|
168
|
+
except zmq.ZMQError as e:
|
|
169
|
+
print(f"Failed to send CreateSubscriber request to datastreamer: {e}")
|
|
170
|
+
exit(1)
|
|
171
|
+
|
|
172
|
+
config, ports = self._receiveConfig()
|
|
173
|
+
if config is None or ports is None:
|
|
174
|
+
print("Failed to create subscriber")
|
|
175
|
+
exit(1)
|
|
176
|
+
self._createConfigState(config, ports)
|
|
177
|
+
|
|
178
|
+
if topic not in self._subscribers:
|
|
179
|
+
print("Internal error, subscriber for topic " + topic + " not created")
|
|
180
|
+
exit(1)
|
|
181
|
+
|
|
182
|
+
def publish(self, topic, data):
|
|
183
|
+
if topic not in self._publishers:
|
|
184
|
+
print("Publisher for topic " + topic + " does not exist")
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
self._publishers[topic].publish(data)
|
|
188
|
+
|
|
189
|
+
def receive(self, topic):
|
|
190
|
+
if topic not in self._subscribers:
|
|
191
|
+
print("Subscriber for topic " + topic + " does not exist")
|
|
192
|
+
return
|
|
193
|
+
|
|
194
|
+
self._subscribers[topic].receive()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class _Publisher:
|
|
198
|
+
def __init__(self, context, port, topic, ipc=False):
|
|
199
|
+
self._topic = topic
|
|
200
|
+
self._topicBytes = topic.encode()
|
|
201
|
+
self._publisherSocket = context.socket(zmq.PUB)
|
|
202
|
+
address = _getAddress(port, ipc)
|
|
203
|
+
try:
|
|
204
|
+
self._publisherSocket.bind(address)
|
|
205
|
+
except zmq.ZMQError as e:
|
|
206
|
+
print(f"Failed to open publish socket on address {address} error: {e}")
|
|
207
|
+
exit(1)
|
|
208
|
+
print(f"Bound to publish socket on address {address} for topic {topic}")
|
|
209
|
+
|
|
210
|
+
def __enter__(self):
|
|
211
|
+
return self
|
|
212
|
+
|
|
213
|
+
def __exit__(self, type, value, traceback):
|
|
214
|
+
self.close()
|
|
215
|
+
|
|
216
|
+
def close(self):
|
|
217
|
+
self._publisherSocket.close()
|
|
218
|
+
|
|
219
|
+
def publish(self, msg):
|
|
220
|
+
if type(msg) == type(""):
|
|
221
|
+
msgData = msg.encode()
|
|
222
|
+
else:
|
|
223
|
+
msgData = msg
|
|
224
|
+
self._publisherSocket.send_multipart([self._topicBytes, msgData])
|
|
225
|
+
|
|
226
|
+
class _Subscriber:
|
|
227
|
+
def __init__(self, context, port, topic, ipc=False):
|
|
228
|
+
self._topic = topic
|
|
229
|
+
self._subscriberSocket = context.socket(zmq.SUB)
|
|
230
|
+
address = _getAddress(port, ipc)
|
|
231
|
+
try:
|
|
232
|
+
self._subscriberSocket.connect(address)
|
|
233
|
+
except zmq.ZMQError as e:
|
|
234
|
+
print(f"Failed to open subscribe socket on address {address} error: {e}")
|
|
235
|
+
exit(1)
|
|
236
|
+
self._subscriberSocket.setsockopt(zmq.SUBSCRIBE, topic.encode())
|
|
237
|
+
print(f"Bound to subscribe socket on address {address} for topic {topic}")
|
|
238
|
+
|
|
239
|
+
def __enter__(self):
|
|
240
|
+
return self
|
|
241
|
+
|
|
242
|
+
def __exit__(self, type, value, traceback):
|
|
243
|
+
self.close()
|
|
244
|
+
|
|
245
|
+
def close(self):
|
|
246
|
+
self._subscriberSocket.close()
|
|
247
|
+
|
|
248
|
+
def receive(self):
|
|
249
|
+
return self._subscriberSocket.recv_multipart()[1].decode()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: fleetmqsdk
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A convenient SDK for FleetMQ
|
|
5
|
+
Author: Nicole
|
|
6
|
+
Author-email: nicole@fleetmq.io
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Requires-Dist: google-api-python-client
|
|
10
|
+
Requires-Dist: pyzmq
|
|
11
|
+
Requires-Dist: setuptools
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: author-email
|
|
14
|
+
Dynamic: classifier
|
|
15
|
+
Dynamic: requires-dist
|
|
16
|
+
Dynamic: summary
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
setup.py
|
|
2
|
+
fleetmqsdk/Abc_config_pb2.py
|
|
3
|
+
fleetmqsdk/Message_pb2.py
|
|
4
|
+
fleetmqsdk/__init__.py
|
|
5
|
+
fleetmqsdk/fleetmqsdk.py
|
|
6
|
+
fleetmqsdk.egg-info/PKG-INFO
|
|
7
|
+
fleetmqsdk.egg-info/SOURCES.txt
|
|
8
|
+
fleetmqsdk.egg-info/dependency_links.txt
|
|
9
|
+
fleetmqsdk.egg-info/requires.txt
|
|
10
|
+
fleetmqsdk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fleetmqsdk
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='fleetmqsdk',
|
|
5
|
+
version='0.0.1',
|
|
6
|
+
description='A convenient SDK for FleetMQ',
|
|
7
|
+
author='Nicole',
|
|
8
|
+
author_email='nicole@fleetmq.io',
|
|
9
|
+
packages=find_packages(),
|
|
10
|
+
install_requires=[
|
|
11
|
+
'google-api-python-client',
|
|
12
|
+
'pyzmq',
|
|
13
|
+
'setuptools'
|
|
14
|
+
],
|
|
15
|
+
classifiers=[
|
|
16
|
+
'Programming Language :: Python :: 3',
|
|
17
|
+
'License :: OSI Approved :: MIT License',
|
|
18
|
+
],
|
|
19
|
+
)
|