ironflock 0.1.1__py3-none-any.whl → 1.0.5__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.
- ironflock/AutobahnConnection.py +14 -4
- ironflock/__init__.py +1 -1
- ironflock/ironflock.py +49 -25
- ironflock-1.0.5.dist-info/METADATA +90 -0
- ironflock-1.0.5.dist-info/RECORD +8 -0
- {ironflock-0.1.1.dist-info → ironflock-1.0.5.dist-info}/WHEEL +1 -1
- ironflock-0.1.1.dist-info/METADATA +0 -80
- ironflock-0.1.1.dist-info/RECORD +0 -8
- {ironflock-0.1.1.dist-info → ironflock-1.0.5.dist-info/licenses}/LICENSE +0 -0
- {ironflock-0.1.1.dist-info → ironflock-1.0.5.dist-info}/top_level.txt +0 -0
ironflock/AutobahnConnection.py
CHANGED
|
@@ -9,8 +9,18 @@ try:
|
|
|
9
9
|
except:
|
|
10
10
|
raise Exception("Environment variable SWARM_KEY not set!")
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
try:
|
|
13
|
+
APP_KEY = os.environ["APP_KEY"]
|
|
14
|
+
except:
|
|
15
|
+
raise Exception("Environment variable APP_KEY not set!")
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
ENV = os.environ["ENV"].lower()
|
|
19
|
+
except:
|
|
20
|
+
raise Exception("Environment variable ENV not set!")
|
|
21
|
+
|
|
22
|
+
# CB_REALM = "userapps"
|
|
23
|
+
CB_REALM = f"realm-{SWARM_KEY}-{APP_KEY}-{ENV}"
|
|
14
24
|
|
|
15
25
|
DATAPODS_WS_URI = "wss://cbw.datapods.io/ws-ua-usr"
|
|
16
26
|
STUDIO_WS_URI_OLD = "wss://cbw.record-evolution.com/ws-ua-usr"
|
|
@@ -69,7 +79,7 @@ class AppSession(ApplicationSession):
|
|
|
69
79
|
def create_application_session(
|
|
70
80
|
serial_number: str = None,
|
|
71
81
|
) -> Tuple[ApplicationSession, ApplicationRunner]:
|
|
72
|
-
"""Creates an Autobahn ApplicationSession and ApplicationRunner, which connects to the
|
|
82
|
+
"""Creates an Autobahn ApplicationSession and ApplicationRunner, which connects to the IronFlock Platform
|
|
73
83
|
|
|
74
84
|
Args:
|
|
75
85
|
serial_number (str, optional): serial_number of device.
|
|
@@ -91,7 +101,7 @@ def create_application_session(
|
|
|
91
101
|
|
|
92
102
|
|
|
93
103
|
def create_application_component(serial_number: str = None) -> Component:
|
|
94
|
-
"""Creates an Autobahn Component, which connects to the
|
|
104
|
+
"""Creates an Autobahn Component, which connects to the IronFlock Platform
|
|
95
105
|
|
|
96
106
|
Args:
|
|
97
107
|
serial_number (str, optional): serial_number of device.
|
ironflock/__init__.py
CHANGED
ironflock/ironflock.py
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import asyncio
|
|
2
3
|
from typing import Optional
|
|
3
4
|
from autobahn.asyncio.component import Component, run
|
|
4
5
|
from autobahn.wamp.interfaces import ISession
|
|
5
|
-
from autobahn.wamp.types import PublishOptions
|
|
6
|
+
from autobahn.wamp.types import PublishOptions, RegisterOptions
|
|
6
7
|
from autobahn.wamp.request import Publication
|
|
7
8
|
|
|
8
9
|
from ironflock.AutobahnConnection import getSerialNumber, create_application_component
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class IronFlock:
|
|
12
|
-
"""
|
|
13
|
+
"""Conveniance class for easy-to-use message publishing in the IronFlock platform.
|
|
13
14
|
|
|
14
15
|
Example:
|
|
15
16
|
|
|
16
|
-
rw = IronFlock()
|
|
17
|
-
|
|
18
17
|
async def main():
|
|
19
18
|
while True:
|
|
20
|
-
publication = await
|
|
19
|
+
publication = await ironFlock.publish("test.publish.pw", 1, "two", 3, foo="bar")
|
|
21
20
|
print(publication)
|
|
22
21
|
await asyncio.sleep(3)
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
if __name__ == "__main__":
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
ironflock = IronFlock(mainFunc=main)
|
|
26
|
+
ironFlock.run()
|
|
28
27
|
"""
|
|
29
28
|
|
|
30
29
|
def __init__(self, serial_number: str = None, mainFunc=None) -> None:
|
|
@@ -36,6 +35,7 @@ class IronFlock:
|
|
|
36
35
|
"""
|
|
37
36
|
self._serial_number = getSerialNumber(serial_number)
|
|
38
37
|
self._device_name = os.environ.get("DEVICE_NAME")
|
|
38
|
+
self._device_key = os.environ.get("DEVICE_KEY")
|
|
39
39
|
self._component = create_application_component(serial_number)
|
|
40
40
|
self._session: ISession = None
|
|
41
41
|
self.mainFunc = mainFunc
|
|
@@ -44,17 +44,22 @@ class IronFlock:
|
|
|
44
44
|
async def onJoin(session, details):
|
|
45
45
|
print("component joined")
|
|
46
46
|
self._session = session
|
|
47
|
+
self._main_task = asyncio.create_task(mainFunc())
|
|
48
|
+
|
|
47
49
|
if self.mainFunc:
|
|
48
50
|
await self.mainFunc()
|
|
49
51
|
|
|
50
52
|
@self._component.on_disconnect
|
|
51
|
-
def onDisconnect(*args, **kwargs):
|
|
52
|
-
print("component disconnected")
|
|
53
|
-
self._session = None
|
|
54
|
-
|
|
55
53
|
@self._component.on_leave
|
|
56
|
-
def onLeave(*args, **kwargs):
|
|
54
|
+
async def onLeave(*args, **kwargs):
|
|
57
55
|
print("component left")
|
|
56
|
+
if self._main_task:
|
|
57
|
+
self._main_task.cancel()
|
|
58
|
+
try:
|
|
59
|
+
await self._main_task
|
|
60
|
+
except asyncio.CancelledError:
|
|
61
|
+
pass
|
|
62
|
+
self._main_task = None
|
|
58
63
|
self._session = None
|
|
59
64
|
|
|
60
65
|
@property
|
|
@@ -76,7 +81,7 @@ class IronFlock:
|
|
|
76
81
|
return self._session
|
|
77
82
|
|
|
78
83
|
async def publish(self, topic: str, *args, **kwargs) -> Optional[Publication]:
|
|
79
|
-
"""Publishes to the
|
|
84
|
+
"""Publishes to the IronFlock Platform Message Router
|
|
80
85
|
|
|
81
86
|
Args:
|
|
82
87
|
topic (str): The URI of the topic to publish to, e.g. "com.myapp.mytopic1"
|
|
@@ -88,6 +93,7 @@ class IronFlock:
|
|
|
88
93
|
|
|
89
94
|
extra = {
|
|
90
95
|
"DEVICE_SERIAL_NUMBER": self._serial_number,
|
|
96
|
+
"DEVICE_KEY": self._device_key,
|
|
91
97
|
"DEVICE_NAME": self._device_name,
|
|
92
98
|
"options": PublishOptions(acknowledge=True),
|
|
93
99
|
}
|
|
@@ -102,6 +108,8 @@ class IronFlock:
|
|
|
102
108
|
"""Update the location of the device registered in the platform
|
|
103
109
|
This will update the device's location in the master data of the platform.
|
|
104
110
|
The maps in the device or group overviews will reflect the new device location in realtime.
|
|
111
|
+
The location history will not be stored in the platform.
|
|
112
|
+
If you need location history, then create a dedicated table for it.
|
|
105
113
|
"""
|
|
106
114
|
|
|
107
115
|
payload = {
|
|
@@ -111,18 +119,43 @@ class IronFlock:
|
|
|
111
119
|
|
|
112
120
|
extra = {
|
|
113
121
|
"DEVICE_SERIAL_NUMBER": self._serial_number,
|
|
122
|
+
"DEVICE_KEY": self._device_key,
|
|
114
123
|
"DEVICE_NAME": self._device_name
|
|
115
124
|
}
|
|
116
125
|
|
|
117
126
|
if hasattr(self, "_session") and hasattr(self._session, "call"):
|
|
118
127
|
res = await self._session.call('ironflock.location_service.update', payload, **extra)
|
|
119
128
|
return res
|
|
129
|
+
|
|
130
|
+
async def register_function(self, topic: str, func):
|
|
131
|
+
"""Registers a function to be called when a message is received on the given topic.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
topic (str): The URI of the topic to register the function for, e.g. "example.mytopic1".
|
|
135
|
+
func (callable): The function to call when a message is received on the topic.
|
|
136
|
+
"""
|
|
137
|
+
swarm_key = os.environ.get("SWARM_KEY")
|
|
138
|
+
app_key = os.environ.get("APP_KEY")
|
|
139
|
+
env_value = os.environ.get("ENV")
|
|
140
|
+
|
|
141
|
+
topic = f"{swarm_key}.{self._device_key}.{app_key}.{env_value}.{topic}"
|
|
142
|
+
|
|
143
|
+
if self._session is not None:
|
|
144
|
+
await self._session.register(topic, func, options=RegisterOptions(force_reregister=True))
|
|
145
|
+
else:
|
|
146
|
+
print("cannot register function, not connected")
|
|
120
147
|
|
|
121
148
|
async def publish_to_table(
|
|
122
149
|
self, tablename: str, *args, **kwargs
|
|
123
150
|
) -> Optional[Publication]:
|
|
124
|
-
"""Publishes Data to a Table in the
|
|
125
|
-
|
|
151
|
+
"""Publishes Data to a Table in the IronFlock Platform. This is a conveniance function.
|
|
152
|
+
You can achieve the same results by simply publishing a payload to the topic
|
|
153
|
+
|
|
154
|
+
[SWARM_KEY].[APP_KEY].[your_table_name]
|
|
155
|
+
|
|
156
|
+
The SWARM_KEY and APP_KEY are provided as environment variables to the device container.
|
|
157
|
+
The also provided ENV variable holds either PROD or DEV to decide which topic to use, above.
|
|
158
|
+
This function automatically detects the environment and publishes to the correct table.
|
|
126
159
|
Args:
|
|
127
160
|
tablename (str): The table name of the table to publish to, e.g. "sensordata"
|
|
128
161
|
|
|
@@ -144,16 +177,7 @@ class IronFlock:
|
|
|
144
177
|
if app_key is None:
|
|
145
178
|
raise Exception("Environment variable APP_KEY not set!")
|
|
146
179
|
|
|
147
|
-
|
|
148
|
-
raise Exception("Environment variable ENV not set!")
|
|
149
|
-
|
|
150
|
-
if not env_value in ["DEV", "PROD"]:
|
|
151
|
-
raise Exception("Environment variable ENV must be 'PROD' or 'DEV'!")
|
|
152
|
-
|
|
153
|
-
if env_value == "PROD":
|
|
154
|
-
topic = f"{swarm_key}.{app_key}.{tablename}"
|
|
155
|
-
else:
|
|
156
|
-
topic = f"dev.{swarm_key}.{app_key}.{tablename}"
|
|
180
|
+
topic = f"{swarm_key}.{app_key}.{tablename}"
|
|
157
181
|
|
|
158
182
|
pub = await self.publish(topic, *args, **kwargs)
|
|
159
183
|
return pub
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ironflock
|
|
3
|
+
Version: 1.0.5
|
|
4
|
+
Summary: SDK to integrate your IronFlock Industry 4 Apps with the IronFlock Data Infrastructure
|
|
5
|
+
Home-page: https://github.com/RecordEvolution/ironflock-py
|
|
6
|
+
Author: Record Evolution GmbH
|
|
7
|
+
Author-email: marko.petzold@record-evolution.de
|
|
8
|
+
License: MIT
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: autobahn[asyncio,serialization]==22.3.2
|
|
13
|
+
Dynamic: author
|
|
14
|
+
Dynamic: author-email
|
|
15
|
+
Dynamic: description
|
|
16
|
+
Dynamic: description-content-type
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: license
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
Dynamic: requires-dist
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# ironflock
|
|
25
|
+
|
|
26
|
+
## About
|
|
27
|
+
|
|
28
|
+
With this library you can publish data from your apps on your IoT edge hardware to the fleet data storage of the [IronFlock](https://studio.ironflock.com) devops platform.
|
|
29
|
+
When this library is used on a certain device the library automatically uses the private messaging realm (Unified Name Space)
|
|
30
|
+
of the device's fleet and the data is collected in the respective fleet database.
|
|
31
|
+
|
|
32
|
+
So if you use the library in your app, the data collection will always be private to the app user's fleet.
|
|
33
|
+
|
|
34
|
+
For more information on the IronFlock IoT Devops Platform for engineers and developers visit our [IronFlock](https://www.ironflock.com) home page.
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import asyncio
|
|
39
|
+
from ironflock import IronFlock
|
|
40
|
+
|
|
41
|
+
# create an IronFlock instance to connect to the IronFlock platform data infrastructure.
|
|
42
|
+
# The IronFlock instance handles authentication when run on a device registered in IronFlock.
|
|
43
|
+
ironflock = IronFlock()
|
|
44
|
+
|
|
45
|
+
async def main():
|
|
46
|
+
while True:
|
|
47
|
+
# publish an event (if connection is not established the publish is skipped)
|
|
48
|
+
publication = await ironflock.publish("test.publish.com", {"temperature": 20})
|
|
49
|
+
print(publication)
|
|
50
|
+
await asyncio.sleep(3)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
ironflock = IronFlock(mainFunc=main)
|
|
55
|
+
ironflock.run()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Options
|
|
59
|
+
|
|
60
|
+
The `IronFlock` `__init__` function can be configured with the following options:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
{
|
|
64
|
+
serial_number: string;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**serial_number**: Used to set the serial_number of the device if the `DEVICE_SERIAL_NUMBER` environment variable does not exist. It can also be used if the user wishes to authenticate as another device.
|
|
69
|
+
|
|
70
|
+
## Advanced Usage
|
|
71
|
+
|
|
72
|
+
If you need more control, e.g. acting on lifecycle events (`onJoin`, `onLeave`) take a look at
|
|
73
|
+
the [examples](https://github.com/RecordEvolution/ironflock-py/tree/main/examples) folder.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## Development
|
|
77
|
+
|
|
78
|
+
Install the necessary components if you don't have them already:
|
|
79
|
+
|
|
80
|
+
```shell
|
|
81
|
+
pip install --upgrade setuptools wheel twine
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Build and publish a new pypi package:
|
|
85
|
+
|
|
86
|
+
```shell
|
|
87
|
+
make publish
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Check the package at https://pypi.org/project/ironflock/.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
ironflock/AutobahnConnection.py,sha256=clwEsptqQFjDFn4dUGN4bQyb1cOnPmmNjetfTrRqckY,3687
|
|
2
|
+
ironflock/__init__.py,sha256=J5w21EeWOBHuxr98nMVMXAASa0tYnKppMluxtKL_x4U,264
|
|
3
|
+
ironflock/ironflock.py,sha256=7ugUzrt1yCG_hJAlUKiyMqALZzhrvokHBOgsPDpLxgU,6906
|
|
4
|
+
ironflock-1.0.5.dist-info/licenses/LICENSE,sha256=GpUKjPB381nmkbBIdX74vxXhsNZaNpngTOciss39Pjk,1073
|
|
5
|
+
ironflock-1.0.5.dist-info/METADATA,sha256=9htX7guGxMP0xAqdOg-uWuyy8riEEs37LrPvV1gygQY,2764
|
|
6
|
+
ironflock-1.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
ironflock-1.0.5.dist-info/top_level.txt,sha256=hmMdMPJuvnOTlFKYl1XQOn81vg1DE2LT7xrEXgyxcRA,10
|
|
8
|
+
ironflock-1.0.5.dist-info/RECORD,,
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: ironflock
|
|
3
|
-
Version: 0.1.1
|
|
4
|
-
Summary: Publishing data to a IronFlock Fleet Storage
|
|
5
|
-
Home-page: https://github.com/RecordEvolution/ironflock-python
|
|
6
|
-
Author: Record Evolution GmbH
|
|
7
|
-
Author-email: marko.petzold@record-evolution.de
|
|
8
|
-
License: MIT
|
|
9
|
-
Requires-Python: >=3.6
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Requires-Dist: autobahn[asyncio,compression,serialization] ==22.3.2
|
|
13
|
-
|
|
14
|
-
# ironflock
|
|
15
|
-
|
|
16
|
-
## About
|
|
17
|
-
|
|
18
|
-
With this library you can publishing data to IronFlock fleet storage. When this library is used on a certain device the library automatically uses the private messaging realm (Unified Name Space) of the device's fleet and the data is collected in the respective fleet database.
|
|
19
|
-
|
|
20
|
-
So if you use the library in your app, the data collection will always be private to the app user's fleet.
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
23
|
-
|
|
24
|
-
```python
|
|
25
|
-
import asyncio
|
|
26
|
-
from ironflock import IronFlock
|
|
27
|
-
|
|
28
|
-
# create a ironflock instance, which auto connects to the IronFlock Platform
|
|
29
|
-
# the ironflock instance handles authentication and reconnects when the connection is lost
|
|
30
|
-
rw = IronFlock()
|
|
31
|
-
|
|
32
|
-
async def main():
|
|
33
|
-
while True:
|
|
34
|
-
# publish an event (if connection is not established the publish is skipped)
|
|
35
|
-
publication = await rw.publish("test.publish.com", {"temperature": 20})
|
|
36
|
-
print(publication)
|
|
37
|
-
await asyncio.sleep(3)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if __name__ == "__main__":
|
|
41
|
-
# run the main coroutine
|
|
42
|
-
asyncio.get_event_loop().create_task(main())
|
|
43
|
-
# run the ironflock component
|
|
44
|
-
rw.run()
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Options
|
|
48
|
-
|
|
49
|
-
The `IronFlock` `__init__` function can be configured with the following options:
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
{
|
|
53
|
-
serial_number: string;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**serial_number**: Used to set the serial_number of the device if the `DEVICE_SERIAL_NUMBER` environment variable does not exist. It can also be used if the user wishes to authenticate as another device.
|
|
58
|
-
|
|
59
|
-
## Advanced Usage
|
|
60
|
-
|
|
61
|
-
If you need more control, e.g. acting on lifecycle events (`onJoin`, `onLeave`) take a look at
|
|
62
|
-
the [examples](./examples/) folder.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
## Development
|
|
66
|
-
|
|
67
|
-
Install the necessary components if you don't have them already:
|
|
68
|
-
|
|
69
|
-
```shell
|
|
70
|
-
pip install --upgrade setuptools wheel twine
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Build and publish a new pypi package:
|
|
74
|
-
|
|
75
|
-
```shell
|
|
76
|
-
python setup.py sdist bdist_wheel
|
|
77
|
-
twine upload dist/*
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Check the package at https://pypi.org/project/ironflock/.
|
ironflock-0.1.1.dist-info/RECORD
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
ironflock/AutobahnConnection.py,sha256=IX5VjUhRGq4-zo8cx2CH964pmoPH29sWc0eQAAG60gM,3438
|
|
2
|
-
ironflock/__init__.py,sha256=LsyyAenv7GrvQSmPc3QJDu7_VsK7BDIvbwGC8ebEI9A,265
|
|
3
|
-
ironflock/ironflock.py,sha256=I0T3NvY8kL7TzdjPdn7HfOxMDxsTF2qRhnklRU09dZ4,5385
|
|
4
|
-
ironflock-0.1.1.dist-info/LICENSE,sha256=GpUKjPB381nmkbBIdX74vxXhsNZaNpngTOciss39Pjk,1073
|
|
5
|
-
ironflock-0.1.1.dist-info/METADATA,sha256=HRePXC8dtOLvc-5tkJ347ZJEpTO0__K1pFJp_PsdzaA,2295
|
|
6
|
-
ironflock-0.1.1.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
|
7
|
-
ironflock-0.1.1.dist-info/top_level.txt,sha256=hmMdMPJuvnOTlFKYl1XQOn81vg1DE2LT7xrEXgyxcRA,10
|
|
8
|
-
ironflock-0.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|