Skip to content

Commit ab236a9

Browse files
committed
ftespnow: Publish version 0.1.0 of the library.
* ftespnow: Initial commit * ftespnow: Added function docstrings * ftespnow-server: Added JSON support, and write to dictionary functionality Added the receive_to_json() function, that supports exporting received data to a JSON file, and the receive_to_dict() function, that returns the received data as a dictionary * ftespnow: Fixed typo when importing ".client" extension in __init__.py * ftespnow: Added examples and updated docstrings * ftespnow: Moved manifests.py to the correct folder * ftespnow: Moved __init__.py to the correct folder * ftespnow: Fix .ftespnow/manifest.py. * ftespnow: Fix .ftespnow-client/manifest.py and .ftespnow-server/manifest.py, code formatting, and fixed spelling mistakes. ... Signed-off-by: Guilherme Schneck <guilhermeschneck@gmail.com> * ftespnow: Fix .ftespnow-client/manifest.py and .ftespnow-server/manifest.py, code formatting, and fixed spelling mistakes. * ftespnow: Fix code formatting errors. * ftespnow: Fix code formatting errors. --------- Signed-off-by: Guilherme Schneck <guilhermeschneck@gmail.com>
1 parent 8380c7b commit ab236a9

11 files changed

Lines changed: 573 additions & 2 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
MANIFEST
22
__pycache__
3+
.vscode/
34
*.egg-info
45
*/dist/
56
*.org
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import ftespnow
2+
3+
# Initialize ESP-NOW client
4+
esp = ftespnow.CLIENT()
5+
6+
# Connect to ESP-NOW server
7+
esp.connect("a4f00f772d15") # Change to actual server mac address
8+
9+
# Send a message
10+
message = "Hello"
11+
sent = esp.send_message(message)
12+
if sent: # Check if server received the data
13+
print("Message received by server")
14+
else:
15+
print("Message not received by server")
16+
17+
# Receive a message
18+
received_data = esp.receive_message()
19+
if received_data is None: # Check if any data was received
20+
print("No message was received (timed out)")
21+
else:
22+
print(f"Here is the received data: {received_data}")
23+
24+
# Send a .txt file
25+
txt_sent = esp.send_txt("filepath/filename.txt")
26+
if txt_sent: # Check if server received the data
27+
print("File received by server")
28+
else:
29+
print("File not received by server")
30+
31+
# Send a .json file
32+
json_sent = esp.send_json("filepath/filename.json")
33+
if json_sent: # Check if server received the data
34+
print("File received by server")
35+
else:
36+
print("File not received by server")
37+
38+
# Write received data to .txt file
39+
txt_received = esp.receive_to_txt(
40+
"filepath/filename.txt", mode="w"
41+
) # Set mode to 'w' so file is truncated before writing
42+
if txt_received:
43+
print("File received successfully")
44+
else:
45+
print("No file received. Destination file was not created/modified")
46+
47+
# Write received data to .json file
48+
json_received = esp.receive_to_json(
49+
"filepath/filename.json", mode="w"
50+
) # Set mode to 'w' so file is truncated before writing
51+
if json_received:
52+
print("File received successfully")
53+
else:
54+
print("No file received. Destination file was not created/modified")
55+
56+
# Write received data to a python dictionary
57+
data_dict = esp.receive_to_dict()
58+
print(data_dict)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import ftespnow
2+
3+
# Initialize ESP-NOW client
4+
esp = ftespnow.SERVER()
5+
6+
# Send a message
7+
message = "Hello"
8+
peer = "a4f00f772d15" # Mac address of the client that you want to send data to
9+
sent = esp.send_message(peer, message)
10+
if sent: # Check if client received the data
11+
print("Message received by clientclient")
12+
else:
13+
print("Message not received by client")
14+
15+
# Receive a message
16+
received_data = esp.receive_message()
17+
if received_data is None: # Check if any data was received
18+
print("No message was received (timed out)")
19+
else:
20+
print(f"Here is the received data: {received_data}")
21+
22+
# Send a .txt file
23+
txt_sent = esp.send_txt(peer, "filepath/filename.txt")
24+
if txt_sent: # Check if client received the data
25+
print("File received by client")
26+
else:
27+
print("File not received by client")
28+
29+
# Send a .json file
30+
json_sent = esp.send_json(peer, "filepath/filename.json")
31+
if json_sent: # Check if client received the data
32+
print("File received by client")
33+
else:
34+
print("File not received by client")
35+
36+
# Write received data to .txt file
37+
txt_received = esp.receive_to_txt(
38+
"filepath/filename.txt", mode="w"
39+
) # Set mode to 'w' so file is truncated before writing
40+
if txt_received:
41+
print("File received successfully")
42+
else:
43+
print("No file received. Destination file was not created/modified")
44+
45+
# Write received data to .json file
46+
json_received = esp.receive_to_json(
47+
"filepath/filename.json", mode="w"
48+
) # Set mode to 'w' so file is truncated before writing
49+
if json_received: # Check if any data was received
50+
print("File received successfully")
51+
else:
52+
print("No file received. Destination file was not created/modified")
53+
54+
# Write received data to a python dictionary
55+
data_dict = esp.receive_to_dict() # Will return {} if no data was received
56+
print(data_dict)
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
import espnow
2+
import json
3+
4+
5+
class CLIENT:
6+
def __init__(self, *, timeout: int = 5) -> None:
7+
self.esp = espnow.ESPNow()
8+
self.timeout = timeout
9+
10+
def configure(self, *, timeout: int = 5) -> None:
11+
self.timeout: int = timeout
12+
13+
def connect(self, peer: str) -> None:
14+
self.peer: str = peer
15+
self.esp.active(True)
16+
self.esp.add_peer(self.peer)
17+
18+
def send_message(self, data: str) -> bool:
19+
"""
20+
Send a string
21+
22+
Args:
23+
24+
data (str): Data to be sent
25+
26+
Returns:
27+
28+
bool: Confirmation flag (`True` if data was received, `False` otherwise)
29+
"""
30+
31+
ack: bool = self.esp.send(self.peer, data)
32+
return ack
33+
34+
def receive_message(self, recv_timeout :int = 5) -> list | None:
35+
"""
36+
Receive a string
37+
38+
Args:
39+
40+
recv_timeout (int, optional): Reception timeout. Defaults to 5.
41+
42+
Returns:
43+
44+
list | None: `[<sender's mac address (str)>, <message (str)>]` | `None` if no message is received
45+
"""
46+
47+
received = self.esp.recv(recv_timeout)
48+
if received[0] is None:
49+
return
50+
return received
51+
52+
def send_txt(self, filename: str) -> bool:
53+
"""
54+
Parse and send a `.txt` file as a `string`
55+
56+
Args:
57+
58+
filename (str): Filepath of the desired file to be sent with file name and extension
59+
60+
Returns:
61+
62+
sent (bool): Confirmation flag (`True` if data was received, `False` otherwise)
63+
"""
64+
65+
with open(filename, "r") as f:
66+
data: str = str(f.readlines())
67+
sent: bool = self.send_message(data)
68+
return sent
69+
70+
def send_json(self, filename: str, *, indent: int = 4) -> bool:
71+
"""
72+
Parse and send a `.json` file as a `string`
73+
74+
Args:
75+
76+
filename (str): Filepath of the desired file to be sent with file name and extension
77+
78+
indent (int, optional): Desired indent of the resulting parsed `string` (for formatting purposes). Defaults to 4.
79+
80+
Returns:
81+
82+
sent (bool): Confirmation flag (`True` if data was received, `False` otherwise)
83+
"""
84+
85+
with open(filename, "r") as f:
86+
unparsed = json.load(f)
87+
parsed: str = json.dumps(unparsed, indent=indent)
88+
sent: bool = self.send_message(parsed)
89+
return sent
90+
91+
def receive_to_txt(self, target_file: str, mode: str = "a") -> bool:
92+
"""
93+
Write received `string` into a `.txt` file.
94+
95+
**Will not write or create file if no data is received**
96+
97+
Args:
98+
99+
target_file (str): Filepath of the destination file for the received data with file name and extension.
100+
101+
mode (str, optional): Editing mode
102+
103+
- `r` - Read only
104+
105+
- `w` - Write only (truncates file before writing)
106+
107+
- `x` - Create a new file and open it for writing (raises `FileExistsError` if file already exists)
108+
109+
- `a` - Append to the end of the file (default)
110+
111+
- `b` - Binary mode
112+
113+
- `t` - Text mode
114+
115+
- `+` - Update (read and write)
116+
117+
Read `open()`_ for more information
118+
119+
Returns:
120+
121+
received (bool): Confirmation flag (`True` if data was received, `False` otherwise)
122+
123+
.. _open(): https://docs.python.org/3/library/functions.html#open
124+
"""
125+
126+
if ".txt" not in target_file:
127+
raise SyntaxError("File format must be .txt")
128+
try:
129+
received: bool = False
130+
data: list | None = self.receive_message()
131+
if data is None:
132+
return received
133+
data_list: list[str] = str(data[-1]).split("\n")
134+
if data_list[-1] == "":
135+
data_list = data_list[:-1]
136+
with open(target_file, mode) as f:
137+
f.writelines(data_list)
138+
return not received
139+
except SyntaxError:
140+
raise
141+
142+
def receive_to_json(self, target_file: str, mode: str = "a") -> bool:
143+
"""
144+
Write received `string` into a `.json` file.
145+
146+
**Will not write or create file if no data is received**
147+
148+
Args:
149+
150+
target_file (str): Filepath of the destination file for the received data with file name and extension.
151+
152+
mode (str, optional): Editing mode
153+
154+
- `r` - Read only
155+
156+
- `w` - Write only (truncates file before writing)
157+
158+
- `x` - Create a new file and open it for writing (raises `FileExistsError` if file already exists)
159+
160+
- `a` - Append to the end of the file (default)
161+
162+
- `b` - Binary mode
163+
164+
- `t` - Text mode
165+
166+
- `+` - Update (read and write)
167+
168+
Read `open()`_ for more information
169+
170+
Returns:
171+
172+
received (bool): Confirmation flag (`True` if data was received, `False` otherwise)
173+
174+
.. _open(): https://docs.python.org/3/library/functions.html#open
175+
"""
176+
177+
if ".json" not in target_file:
178+
raise SyntaxError("File format must be .json")
179+
try:
180+
received: bool = False
181+
data: list | None = self.receive_message()
182+
if data is None:
183+
return received
184+
mac: str = str(data[0])
185+
message = json.loads(str(data[-1]))
186+
unparsed: dict = {"mac": mac, "message": message}
187+
with open(target_file, mode) as f:
188+
json.dump(unparsed, f)
189+
return not received
190+
except SyntaxError:
191+
raise
192+
193+
def receive_to_dict(self) -> dict:
194+
"""
195+
Unparses received `string` into a `dict` object
196+
197+
Args:
198+
199+
None:
200+
201+
Returns:
202+
203+
unparsed (dict): `dictionary` object containing unparsed equivalent of the received `.json`
204+
"""
205+
206+
data: list | None = self.receive_message()
207+
if data is None:
208+
return {}
209+
mac: str = str(data[0])
210+
message = json.loads(str(data[-1]))
211+
unparsed: dict = {"mac": mac, "message": message}
212+
return unparsed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
metadata(
2+
description="Client-side commands",
3+
version="0.1.0",
4+
)
5+
6+
require("ftespnow")
7+
package("ftespnow")

0 commit comments

Comments
 (0)