easyhttp-python 0.3.2__tar.gz → 0.4.0a6__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.
- {easyhttp_python-0.3.2/easyhttp_python.egg-info → easyhttp_python-0.4.0a6}/PKG-INFO +16 -11
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/README.md +25 -58
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/README_PY.md +13 -9
- easyhttp_python-0.4.0a6/easyhttp_python/__init__.py +6 -0
- easyhttp_python-0.4.0a6/easyhttp_python/_discovery.py +145 -0
- {easyhttp_python-0.3.2/easyhttp → easyhttp_python-0.4.0a6/easyhttp_python}/core.py +252 -180
- {easyhttp_python-0.3.2/easyhttp → easyhttp_python-0.4.0a6/easyhttp_python}/wrapper.py +35 -29
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6/easyhttp_python.egg-info}/PKG-INFO +16 -11
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/easyhttp_python.egg-info/SOURCES.txt +4 -3
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/easyhttp_python.egg-info/requires.txt +1 -0
- easyhttp_python-0.4.0a6/easyhttp_python.egg-info/top_level.txt +1 -0
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/pyproject.toml +5 -4
- easyhttp_python-0.3.2/easyhttp/__init__.py +0 -9
- easyhttp_python-0.3.2/easyhttp_python.egg-info/top_level.txt +0 -1
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/LICENSE +0 -0
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/easyhttp_python.egg-info/dependency_links.txt +0 -0
- {easyhttp_python-0.3.2 → easyhttp_python-0.4.0a6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: easyhttp-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0a6
|
|
4
4
|
Summary: Simple HTTP-based P2P framework for IoT
|
|
5
5
|
Author-email: slpuk <yarik6052@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -9,7 +9,7 @@ Project-URL: Documentation, https://github.com/slpuk/easyhttp-python#readme
|
|
|
9
9
|
Project-URL: Repository, https://github.com/slpuk/easyhttp-python
|
|
10
10
|
Project-URL: Issue Tracker, https://github.com/slpuk/easyhttp-python/issues
|
|
11
11
|
Keywords: iot,p2p,http,framework
|
|
12
|
-
Classifier: Development Status ::
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
15
|
Classifier: Topic :: Communications
|
|
@@ -27,6 +27,7 @@ License-File: LICENSE
|
|
|
27
27
|
Requires-Dist: fastapi>=0.103.2
|
|
28
28
|
Requires-Dist: uvicorn[standard]>=0.22.0
|
|
29
29
|
Requires-Dist: aiohttp>=3.7.0
|
|
30
|
+
Requires-Dist: loggity>=0.5.0a6
|
|
30
31
|
Provides-Extra: dev
|
|
31
32
|
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
32
33
|
Requires-Dist: black; extra == "dev"
|
|
@@ -36,15 +37,15 @@ Dynamic: license-file
|
|
|
36
37
|
# EasyHTTP
|
|
37
38
|
|
|
38
39
|
[](https://github.com/slpuk/easyhttp-python)
|
|
39
|
-

|
|
41
|
+

|
|
41
42
|

|
|
42
43
|

|
|
43
44
|
|
|
44
45
|
> **A lightweight HTTP-based P2P framework for IoT and device-to-device communication**
|
|
45
46
|
|
|
46
47
|
## 🛠️ Changelog
|
|
47
|
-
- Added
|
|
48
|
+
- Added UDP multicast discovery
|
|
48
49
|
- Fixed some bugs
|
|
49
50
|
|
|
50
51
|
## 📖 About
|
|
@@ -58,7 +59,7 @@ Dynamic: license-file
|
|
|
58
59
|
- **🆔 Human-Readable Device IDs** - Base32 identifiers instead of IP addresses
|
|
59
60
|
- **✅ Easy to Use** - Simple API with minimal setup
|
|
60
61
|
- **🚀 Performance** - Asynchronous code and lightweight libraries(FastAPI/aiohttp)
|
|
61
|
-
|
|
62
|
+
- **⚙️ Auto-detect** - Devices automatically find each other
|
|
62
63
|
|
|
63
64
|
## 🏗️ Architecture
|
|
64
65
|
|
|
@@ -86,7 +87,7 @@ EasyHTTP uses a simple JSON-based command system:
|
|
|
86
87
|
### Basic Example with Callbacks (synchronous)
|
|
87
88
|
```python
|
|
88
89
|
import time
|
|
89
|
-
from
|
|
90
|
+
from easyhttp_python import EasyHTTP
|
|
90
91
|
|
|
91
92
|
# Callback function
|
|
92
93
|
def handle_data(sender_id, data, timestamp):
|
|
@@ -127,10 +128,6 @@ def main():
|
|
|
127
128
|
easy.start() # Starting server
|
|
128
129
|
print(f"Device {easy.id} is running on port 5000!")
|
|
129
130
|
|
|
130
|
-
# Adding device
|
|
131
|
-
easy.add("ABC123", "192.168.1.100", 5000)
|
|
132
|
-
print("Added device ABC123")
|
|
133
|
-
|
|
134
131
|
# Monitoring device's status
|
|
135
132
|
try:
|
|
136
133
|
while True:
|
|
@@ -149,4 +146,12 @@ def main():
|
|
|
149
146
|
if __name__ == "__main__":
|
|
150
147
|
main()
|
|
151
148
|
```
|
|
149
|
+
## 📦 Version History
|
|
150
|
+
|
|
151
|
+
| Version | Date | Changes |
|
|
152
|
+
|---------|------|---------|
|
|
153
|
+
| 0.4.0 | 2026-11-03 | UDP Discovery, auto-detect |
|
|
154
|
+
| 0.3.3 | 2026-03-01 | Fixed imports, renamed to easyhttp_python |
|
|
155
|
+
| 0.3.2 | 2026-02-14 | Context managers |
|
|
156
|
+
|
|
152
157
|
**More examples available on [GitHub](https://github.com/slpuk/easyhttp-python)**
|
|
@@ -2,57 +2,32 @@
|
|
|
2
2
|
[EN README](README.md) | [RU README](README_RU.md)
|
|
3
3
|
> **A lightweight HTTP-based P2P framework for IoT and device-to-device communication**
|
|
4
4
|
|
|
5
|
-

|
|
6
|
+

|
|
7
7
|

|
|
8
8
|

|
|
9
9
|
|
|
10
10
|
> [!WARNING]
|
|
11
|
-
> **Breaking Changes from 0.2
|
|
11
|
+
> **Breaking Changes from 0.3.2**
|
|
12
12
|
>
|
|
13
13
|
> ### API Changes
|
|
14
|
-
> | 0.2.0 | 0.3.2 | Notes |
|
|
15
|
-
> |--------|--------|-------|
|
|
16
|
-
> | `get()` | `fetch()` | Same functionality |
|
|
17
|
-
> | `pull()` | `push()` | Same functionality |
|
|
18
|
-
> | `'on_get'` | `'on_fetch'` | Callback name |
|
|
19
|
-
> | `'on_data_response'` | `'on_data'` | Callback name |
|
|
20
|
-
> | `'on_pull'` | `'on_push'` | Callback name |
|
|
21
|
-
>
|
|
22
|
-
> ### Migration Example
|
|
23
14
|
> ```python
|
|
24
|
-
> # 0.2
|
|
25
|
-
>
|
|
26
|
-
> easy.get("ABC123")
|
|
27
|
-
> easy.pull("ABC123", data)
|
|
28
|
-
>
|
|
29
|
-
> # 0.3.2 (NEW):
|
|
30
|
-
> # Sync
|
|
31
|
-
> easy = EasyHTTP()
|
|
32
|
-
> easy.fetch("ABC123")
|
|
33
|
-
> easy.push("ABC123", data)
|
|
15
|
+
> # 0.3.2 (OLD)
|
|
16
|
+
> from easyhttp import ...
|
|
34
17
|
>
|
|
35
|
-
> #
|
|
36
|
-
>
|
|
37
|
-
|
|
38
|
-
> await easy.push("ABC123", data)
|
|
39
|
-
> ```
|
|
40
|
-
|
|
18
|
+
> # 0.3.3 - newer (NEW)
|
|
19
|
+
> from easyhttp_python import ...
|
|
20
|
+
>```
|
|
41
21
|
|
|
42
22
|
## 🚀 Quick Start
|
|
43
23
|
|
|
44
24
|
### Installation
|
|
45
|
-
> [!NOTE]
|
|
46
|
-
> Both methods require **Git** to be installed.<br>
|
|
47
|
-
> PyPI upload is **preparing**
|
|
48
25
|
|
|
49
26
|
```bash
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
cd easyhttp-python
|
|
53
|
-
pip install -e .
|
|
27
|
+
# Install by PyPI
|
|
28
|
+
pip install easyhttp-python
|
|
54
29
|
|
|
55
|
-
# Or
|
|
30
|
+
# Or from GitHub
|
|
56
31
|
pip install git+https://github.com/slpuk/easyhttp-python.git
|
|
57
32
|
```
|
|
58
33
|
|
|
@@ -60,16 +35,13 @@ pip install git+https://github.com/slpuk/easyhttp-python.git
|
|
|
60
35
|
Syntax with context managers and full code is supported
|
|
61
36
|
|
|
62
37
|
```python
|
|
63
|
-
from
|
|
38
|
+
from easyhttp_python import EasyHTTP
|
|
64
39
|
|
|
65
40
|
def main():
|
|
66
41
|
# Initialize a device with context manager
|
|
67
42
|
with EasyHTTP(debug=True, port=5000) as easy:
|
|
68
43
|
print(f"Device ID: {easy.id}")
|
|
69
44
|
|
|
70
|
-
# Manually add another device
|
|
71
|
-
easy.add("ABC123", "192.168.1.100", 5000)
|
|
72
|
-
|
|
73
45
|
# Ping to check if device is online
|
|
74
46
|
if easy.ping("ABC123"):
|
|
75
47
|
print("Device is online!")
|
|
@@ -93,7 +65,7 @@ if __name__ == "__main__":
|
|
|
93
65
|
|
|
94
66
|
```python
|
|
95
67
|
import asyncio
|
|
96
|
-
from
|
|
68
|
+
from easyhttp_python import EasyHTTPAsync
|
|
97
69
|
|
|
98
70
|
async def main():
|
|
99
71
|
# Initialize a device
|
|
@@ -102,9 +74,6 @@ async def main():
|
|
|
102
74
|
|
|
103
75
|
print(f"Device ID: {easy.id}")
|
|
104
76
|
|
|
105
|
-
# Manually add another device
|
|
106
|
-
easy.add("ABC123", "192.168.1.100", 5000)
|
|
107
|
-
|
|
108
77
|
# Ping to check if device is online
|
|
109
78
|
if await easy.ping("ABC123"):
|
|
110
79
|
print("Device is online!")
|
|
@@ -136,6 +105,7 @@ if __name__ == "__main__":
|
|
|
136
105
|
- **🆔 Human-Readable Device IDs** - Base32 identifiers instead of IP addresses
|
|
137
106
|
- **✅ Easy to Use** - Simple API with minimal setup
|
|
138
107
|
- **🚀 Performance** - Asynchronous code and lightweight libraries(FastAPI/aiohttp)
|
|
108
|
+
- **⚙️ Auto-detect** - Devices automatically find each other
|
|
139
109
|
|
|
140
110
|
## Project Structure
|
|
141
111
|
```
|
|
@@ -143,10 +113,11 @@ easyhttp-python/
|
|
|
143
113
|
├── docs/
|
|
144
114
|
│ ├── EasyHTTP.md # Sync API reference
|
|
145
115
|
│ └── EasyHTTPAsync.md # Async API reference
|
|
146
|
-
├──
|
|
116
|
+
├── easyhttp_python/
|
|
147
117
|
│ ├── __init__.py
|
|
148
|
-
│ ├── core.py
|
|
149
|
-
│
|
|
118
|
+
│ ├── core.py # Main framework file/core
|
|
119
|
+
│ ├── discovery.py # Discovery module
|
|
120
|
+
│ └── wrapper.py # Synchronous wrapper
|
|
150
121
|
├── examples/
|
|
151
122
|
│ ├── async/ # Asynchronous examples
|
|
152
123
|
│ │ ├── basic_ping.py
|
|
@@ -163,6 +134,7 @@ easyhttp-python/
|
|
|
163
134
|
├── .gitignore
|
|
164
135
|
├── LICENSE # MIT license
|
|
165
136
|
├── pyproject.toml # Project config
|
|
137
|
+
├── README_PY.md # Documentation for PyPI
|
|
166
138
|
├── README_RU.md # Russian documentation
|
|
167
139
|
├── README.md # This file
|
|
168
140
|
└── requirements.txt # Project dependencies
|
|
@@ -209,25 +181,20 @@ sequenceDiagram
|
|
|
209
181
|
|
|
210
182
|
## 📦 Installation & Setup
|
|
211
183
|
|
|
212
|
-
###
|
|
213
|
-
> [!NOTE]
|
|
214
|
-
> Both methods require **Git** to be installed.<br>
|
|
215
|
-
> PyPI upload is **preparing**
|
|
184
|
+
### Installation
|
|
216
185
|
|
|
217
186
|
```bash
|
|
218
|
-
# Install
|
|
219
|
-
pip install
|
|
187
|
+
# Install from PyPI
|
|
188
|
+
pip install easyhttp-python
|
|
220
189
|
|
|
221
|
-
# Or
|
|
222
|
-
|
|
223
|
-
cd easyhttp-python
|
|
224
|
-
pip install -e .
|
|
190
|
+
# Or from GitHub
|
|
191
|
+
pip install git+https://github.com/slpuk/easyhttp-python.git
|
|
225
192
|
```
|
|
226
193
|
|
|
227
194
|
### Basic Example with Callbacks(Synchronous)
|
|
228
195
|
```python
|
|
229
196
|
import time
|
|
230
|
-
from
|
|
197
|
+
from easyhttp_python import EasyHTTP
|
|
231
198
|
|
|
232
199
|
# Callback function
|
|
233
200
|
def handle_data(sender_id, data, timestamp):
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# EasyHTTP
|
|
2
2
|
|
|
3
3
|
[](https://github.com/slpuk/easyhttp-python)
|
|
4
|
-

|
|
5
|
+

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
|
|
9
9
|
> **A lightweight HTTP-based P2P framework for IoT and device-to-device communication**
|
|
10
10
|
|
|
11
11
|
## 🛠️ Changelog
|
|
12
|
-
- Added
|
|
12
|
+
- Added UDP multicast discovery
|
|
13
13
|
- Fixed some bugs
|
|
14
14
|
|
|
15
15
|
## 📖 About
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
- **🆔 Human-Readable Device IDs** - Base32 identifiers instead of IP addresses
|
|
24
24
|
- **✅ Easy to Use** - Simple API with minimal setup
|
|
25
25
|
- **🚀 Performance** - Asynchronous code and lightweight libraries(FastAPI/aiohttp)
|
|
26
|
-
|
|
26
|
+
- **⚙️ Auto-detect** - Devices automatically find each other
|
|
27
27
|
|
|
28
28
|
## 🏗️ Architecture
|
|
29
29
|
|
|
@@ -51,7 +51,7 @@ EasyHTTP uses a simple JSON-based command system:
|
|
|
51
51
|
### Basic Example with Callbacks (synchronous)
|
|
52
52
|
```python
|
|
53
53
|
import time
|
|
54
|
-
from
|
|
54
|
+
from easyhttp_python import EasyHTTP
|
|
55
55
|
|
|
56
56
|
# Callback function
|
|
57
57
|
def handle_data(sender_id, data, timestamp):
|
|
@@ -92,10 +92,6 @@ def main():
|
|
|
92
92
|
easy.start() # Starting server
|
|
93
93
|
print(f"Device {easy.id} is running on port 5000!")
|
|
94
94
|
|
|
95
|
-
# Adding device
|
|
96
|
-
easy.add("ABC123", "192.168.1.100", 5000)
|
|
97
|
-
print("Added device ABC123")
|
|
98
|
-
|
|
99
95
|
# Monitoring device's status
|
|
100
96
|
try:
|
|
101
97
|
while True:
|
|
@@ -114,4 +110,12 @@ def main():
|
|
|
114
110
|
if __name__ == "__main__":
|
|
115
111
|
main()
|
|
116
112
|
```
|
|
113
|
+
## 📦 Version History
|
|
114
|
+
|
|
115
|
+
| Version | Date | Changes |
|
|
116
|
+
|---------|------|---------|
|
|
117
|
+
| 0.4.0 | 2026-11-03 | UDP Discovery, auto-detect |
|
|
118
|
+
| 0.3.3 | 2026-03-01 | Fixed imports, renamed to easyhttp_python |
|
|
119
|
+
| 0.3.2 | 2026-02-14 | Context managers |
|
|
120
|
+
|
|
117
121
|
**More examples available on [GitHub](https://github.com/slpuk/easyhttp-python)**
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""UDP multicast discovery module for EasyHTTP."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import socket
|
|
5
|
+
import struct
|
|
6
|
+
import json
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .core import EasyHTTPAsync
|
|
11
|
+
|
|
12
|
+
from loggity import Logger, Colors, LoggerConfig
|
|
13
|
+
log_config = LoggerConfig(
|
|
14
|
+
colored = True,
|
|
15
|
+
timestamps = False,
|
|
16
|
+
timeformat = None,
|
|
17
|
+
file = None
|
|
18
|
+
)
|
|
19
|
+
log = Logger(config = log_config)
|
|
20
|
+
|
|
21
|
+
class Discovery:
|
|
22
|
+
"""Manages UDP multicast discovery for EasyHTTP devices."""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
parent: "EasyHTTPAsync",
|
|
27
|
+
multicast_group: str = "224.0.0.106",
|
|
28
|
+
multicast_port: int = 37020,
|
|
29
|
+
):
|
|
30
|
+
self.parent = parent
|
|
31
|
+
self.version = self.parent.__version__
|
|
32
|
+
self.multicast_group = multicast_group
|
|
33
|
+
self.multicast_port = multicast_port
|
|
34
|
+
self.discovery_task: asyncio.Task | None = None
|
|
35
|
+
self.enabled = False
|
|
36
|
+
|
|
37
|
+
async def start(self):
|
|
38
|
+
"""Start discovery listener and broadcaster."""
|
|
39
|
+
self.enabled = True
|
|
40
|
+
self.discovery_task = asyncio.create_task(self._discovery_loop())
|
|
41
|
+
|
|
42
|
+
async def stop(self):
|
|
43
|
+
"""Stop discovery tasks."""
|
|
44
|
+
if self.discovery_task:
|
|
45
|
+
self.discovery_task.cancel()
|
|
46
|
+
try:
|
|
47
|
+
await self.discovery_task
|
|
48
|
+
except asyncio.CancelledError:
|
|
49
|
+
pass
|
|
50
|
+
self.discovery_task = None
|
|
51
|
+
|
|
52
|
+
async def _discovery_loop(self):
|
|
53
|
+
"""Run listener and broadcaster concurrently."""
|
|
54
|
+
listener = asyncio.create_task(self._listen_multicast())
|
|
55
|
+
broadcaster = asyncio.create_task(self._broadcast_presence())
|
|
56
|
+
await asyncio.gather(listener, broadcaster)
|
|
57
|
+
|
|
58
|
+
async def _listen_multicast(self):
|
|
59
|
+
"""Listen for DISCOVERY messages from other devices."""
|
|
60
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
|
61
|
+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
62
|
+
sock.bind(("", self.multicast_port))
|
|
63
|
+
|
|
64
|
+
mreq = struct.pack(
|
|
65
|
+
"4sl", socket.inet_aton(self.multicast_group), socket.INADDR_ANY
|
|
66
|
+
)
|
|
67
|
+
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
|
|
68
|
+
sock.setblocking(False)
|
|
69
|
+
|
|
70
|
+
loop = asyncio.get_event_loop()
|
|
71
|
+
while True:
|
|
72
|
+
try:
|
|
73
|
+
data, addr = await loop.sock_recvfrom(sock, 1024)
|
|
74
|
+
await self._handle_discovery_message(data, addr)
|
|
75
|
+
except asyncio.CancelledError:
|
|
76
|
+
break
|
|
77
|
+
except Exception as e:
|
|
78
|
+
if self.parent.debug:
|
|
79
|
+
log.custom("DISCOVERY", Colors.RED, e)
|
|
80
|
+
|
|
81
|
+
async def _broadcast_presence(self):
|
|
82
|
+
"""Periodically broadcast DISCOVERY messages."""
|
|
83
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
|
84
|
+
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
|
|
85
|
+
|
|
86
|
+
while True:
|
|
87
|
+
try:
|
|
88
|
+
packet = {
|
|
89
|
+
"version": self.version,
|
|
90
|
+
"type": self.parent.commands.DISCOVERY.value,
|
|
91
|
+
"id": self.parent.id,
|
|
92
|
+
"port": self.parent.port,
|
|
93
|
+
}
|
|
94
|
+
sock.sendto(
|
|
95
|
+
json.dumps(packet).encode(),
|
|
96
|
+
(self.multicast_group, self.multicast_port),
|
|
97
|
+
)
|
|
98
|
+
await asyncio.sleep(30)
|
|
99
|
+
except asyncio.CancelledError:
|
|
100
|
+
break
|
|
101
|
+
except Exception as e:
|
|
102
|
+
if self.parent.debug:
|
|
103
|
+
log.custom("DISCOVERY", Colors.RED, e)
|
|
104
|
+
|
|
105
|
+
async def _handle_discovery_message(self, data: bytes, addr: tuple):
|
|
106
|
+
"""Process incoming discovery messages."""
|
|
107
|
+
try:
|
|
108
|
+
message = json.loads(data.decode())
|
|
109
|
+
cmd_type = message.get("type")
|
|
110
|
+
|
|
111
|
+
# Received DISCOVERY -> send DISCOVERY_ACK
|
|
112
|
+
if cmd_type == self.parent.commands.DISCOVERY.value:
|
|
113
|
+
device_id = message.get("id")
|
|
114
|
+
device_port = message.get("port")
|
|
115
|
+
|
|
116
|
+
if device_id and device_id != self.parent.id:
|
|
117
|
+
ack_packet = {
|
|
118
|
+
"version": self.version,
|
|
119
|
+
"type": self.parent.commands.DISCOVERY_ACK.value,
|
|
120
|
+
"id": self.parent.id,
|
|
121
|
+
"port": self.parent.port,
|
|
122
|
+
}
|
|
123
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
124
|
+
sock.sendto(
|
|
125
|
+
json.dumps(ack_packet).encode(),
|
|
126
|
+
(addr[0], self.multicast_port),
|
|
127
|
+
)
|
|
128
|
+
if self.parent.debug:
|
|
129
|
+
log.custom("DISCOVERY", Colors.GREEN, f"Responded to {device_id} at {addr[0]}")
|
|
130
|
+
|
|
131
|
+
# Received DISCOVERY_ACK -> add device
|
|
132
|
+
elif cmd_type == self.parent.commands.DISCOVERY_ACK.value:
|
|
133
|
+
device_id = message.get("id")
|
|
134
|
+
device_port = message.get("port")
|
|
135
|
+
|
|
136
|
+
if device_id and device_id != self.parent.id:
|
|
137
|
+
if device_id not in self.parent.devices:
|
|
138
|
+
self.parent.add(device_id, addr[0], device_port)
|
|
139
|
+
if self.parent.debug:
|
|
140
|
+
log.custom("DISCOVERY", Colors.GREEN, f"Found device {device_id} at {addr[0]}")
|
|
141
|
+
asyncio.create_task(self.parent.ping(device_id))
|
|
142
|
+
|
|
143
|
+
except Exception as e:
|
|
144
|
+
if self.parent.debug:
|
|
145
|
+
log.custom("DISCOVERY", Colors.RED, e)
|