Skip to content

Commit 1622d7b

Browse files
committed
Updating Coap documentation after esp-idf 4 update
1 parent c6a895a commit 1622d7b

File tree

1 file changed

+178
-55
lines changed
  • content/firmwareapi/pycom/network

1 file changed

+178
-55
lines changed

content/firmwareapi/pycom/network/coap.md

+178-55
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,29 @@ aliases:
77
---
88
This module implements a CoAp Server and Client, operating as both at the same time.
99

10-
## Usage Example
10+
## Usage Example of CoAp Server
1111

1212
```python
1313

1414
from network import WLAN
1515
from network import Coap
16-
import uselect
1716
import _thread
1817

19-
# The callback that handles the responses generated from the requests sent to a CoAp Server
20-
def response_callback(code, id_param, type_param, token, payload):
21-
print("Code: {}".format(code))
22-
# The ID can be used to pair the requests with the responses
23-
print("ID: {}".format(id_param))
24-
print("Type: {}".format(type_param))
25-
print("Token: {}".format(token))
26-
print("Payload: {}".format(payload))
27-
28-
# Thread handling the sockets
29-
def socket_thread(p, coap_socket):
18+
# Thread handling the CoAp Server
19+
def coap_thread():
3020
while True:
31-
# Wait for any socket to become available
32-
sockets = p.poll()
33-
for s in sockets:
34-
sock = s[0]
35-
event = s[1]
36-
if(event & uselect.POLLIN):
37-
# Check if the socket belongs to the CoAp module
38-
if(sock == coap_socket):
39-
# Call Coap.read() which parses the incoming CoAp message
40-
Coap.read()
21+
# Call Coap.read() without specyfing timeout value, in this way it handled all requests sent to the CoAp Server silently
22+
Coap.read()
4123

4224

4325
# Connect to the network
4426
wlan = WLAN(mode=WLAN.STA)
4527
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
4628

47-
# Initialise the CoAp module
29+
# Initialize Coap module as CoAp Server
4830
Coap.init(str(wlan.ifconfig()[0]), service_discovery=True)
4931

50-
# Add a resource with a default value and a plain text content format
32+
# Add a resource with default value and plain text content format
5133
r = Coap.add_resource("resource1", media_type=Coap.MEDIATYPE_TEXT_PLAIN, value="default_value")
5234
# Add an attribute to the resource
5335
r.add_attribute("title", "resource1")
@@ -61,26 +43,135 @@ r = Coap.add_resource("resource2", media_type=Coap.MEDIATYPE_APP_XML, etag=True)
6143
# Configure the possible operations on the resource
6244
r.callback(Coap.REQUEST_GET | Coap.REQUEST_POST | Coap.REQUEST_PUT | Coap.REQUEST_DELETE, True)
6345

64-
# Register the response handler for the requests that the module initiates as a CoAp Client
46+
# Start a new thread which handles the CoAp Server
47+
_thread.start_new_thread(coap_thread, ())
48+
49+
```
50+
51+
## Usage Example of CoAp Client in blocking mode
52+
53+
```python
54+
55+
from network import WLAN
56+
from network import Coap
57+
import _thread
58+
59+
# Callback handling the responses to the requests sent to a Coap Server
60+
def response_callback(code, id_param, type_param, token, payload):
61+
print("Code: {}".format(code))
62+
# The ID can be used to pair the requests with the responses
63+
print("ID: {}".format(id_param))
64+
print("Type: {}".format(type_param))
65+
print("Token: {}".format(token))
66+
print("Payload: {}".format(payload))
67+
68+
# Thread handling the sockets
69+
def coap_thread():
70+
while True:
71+
# Using Coap.read() without timeout value means that if no new packet arrives to any of the client sessions registered before this is called, then this function will never return
72+
Coap.read()
73+
74+
75+
# Connect to the network
76+
wlan = WLAN(mode=WLAN.STA)
77+
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
78+
79+
# Initialize Coap module
80+
Coap.init(str(wlan.ifconfig()[0]), service_discovery=True)
81+
82+
# Register the response handler for the requests the module initiates as a Coap Client
6583
Coap.register_response_handler(response_callback)
6684

67-
# Get the UDP socket created for the CoAp module
68-
coap_server_socket = Coap.socket()
85+
# As the Coap.read() will be called in a form that it blocks until no new data arrives to the socket, it is only safe
86+
# to create new client sessions before Coap.read() is called
87+
session = Coap.new_client_session("192.168.0.234", 5683)
6988

70-
# Create a new poll object
71-
p = uselect.poll()
72-
# Register the CoAp module's socket to the poll
73-
p.register(coap_server_socket, uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR)
89+
# Start a new thread which calls Coap.read() which will block until no new packet arrives to the socket
90+
_thread.start_new_thread(coap_thread, ())
7491

75-
# Start a new thread which will handle the sockets of "p" poll
76-
_thread.start_new_thread(socket_thread, (p, coap_server_socket))
92+
# After this point it is not safe to create new Coap Client Session as they might not be handled by Coap.read()
7793

78-
# Send a request to a CoAp server
79-
id = Coap.send_request("192.168.0.234", Coap.REQUEST_GET, uri_port=5683, uri_path=".well-known/core", payload="payload", token="token1", include_options=True)
94+
# Request to a normal CoAp Server
95+
id = session.send_request(Coap.REQUEST_GET, uri_path=".well-known/core", payload="payload", token="token1", include_options=True)
96+
print(id)
97+
# Request to a normal CoAp Server
98+
id = session.send_request(Coap.REQUEST_GET, uri_path="time", payload="payload", token="token2", include_options=True)
99+
print(id)
100+
# Request to a normal CoAp Server
101+
id = session.send_request(Coap.REQUEST_PUT, uri_path="time",content_format=Coap.MEDIATYPE_TEXT_PLAIN, payload="ABCD", token="token3", include_options=True)
102+
print(id)
103+
# Request to a Dish Telemetry server, payload is the AMQP message, token is maximum 8 bytes containing the IMEI or IMSI id, no options should be present
104+
imei = int('359738090028145').to_bytes(8, 'big')
105+
id = session.send_request(Coap.REQUEST_GET, payload="amqp://artemis:5672/dish.app1.FjhBV78.telemetry", token=imei, include_options=False)
80106
print(id)
81107

82108
```
83109

110+
## Usage Example of CoAp Client in non-blocking mode
111+
112+
```python
113+
114+
from network import WLAN
115+
from network import Coap
116+
import _thread
117+
118+
# Callback handling the responses to the requests sent to a Coap Server
119+
def response_callback(code, id_param, type_param, token, payload):
120+
print("Code: {}".format(code))
121+
# The ID can be used to pair the requests with the responses
122+
print("ID: {}".format(id_param))
123+
print("Type: {}".format(type_param))
124+
print("Token: {}".format(token))
125+
print("Payload: {}".format(payload))
126+
127+
# Thread handling the sockets
128+
def coap_thread():
129+
while True:
130+
# Wait only 3 seconds for new packets then return back
131+
# In the next call it will also handle any new CoAp Client Sessions created during the previous call
132+
Coap.read(3000)
133+
134+
135+
# Connect to the network
136+
wlan = WLAN(mode=WLAN.STA)
137+
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
138+
139+
# Initialize Coap module, to be used only as a CoAp Client
140+
Coap.init()
141+
142+
# Start a new thread which handles the CoAp, it is safe to start as soon as possible as the Coap.read() has timeout specified
143+
# After this point it is safe to create new CoAp Client Sessions, it will be processed by the coap_thread correctly as Coap.read() is used with timeout value
144+
_thread.start_new_thread(coap_thread, ())
145+
146+
# Register the response handler for the requests the module initiates as a Coap Client
147+
Coap.register_response_handler(response_callback)
148+
149+
# Create a new client session on demand
150+
session1 = Coap.new_client_session("192.168.0.234", 5683)
151+
152+
# Request to a normal CoAp Server via CoAp Client Session: session1
153+
id = session1.send_request(Coap.REQUEST_GET, uri_path=".well-known/core", token="session1")
154+
print(id)
155+
# Request to a normal CoAp Server via CoAp Client Session: session1
156+
id = session1.send_request(Coap.REQUEST_GET, uri_path="time", token="session1")
157+
print(id)
158+
159+
# Create again a new CoAp Client Session on demand, without restriction
160+
session2 = Coap.new_client_session("192.168.0.236", 5683)
161+
162+
# Request to a normal CoAp server via CoAp Client Session: session2
163+
id = session2.send_request(Coap.REQUEST_GET, uri_path=".well-known/core")
164+
print(id)
165+
# Request to a normal CoAp server via CoAp Client Session: session2
166+
id = session2.send_request(Coap.REQUEST_GET, uri_path="resource1")
167+
print(id)
168+
# Request to a normal CoAp server via CoAp Client Session: session2
169+
id = session2.send_request(Coap.REQUEST_POST, uri_path="resource1", payload="new_value")
170+
print(id)
171+
172+
```
173+
174+
84175
## Initialization
85176

86177
#### Coap.init(address, *, port=5683, service_discovery=False)
@@ -89,19 +180,15 @@ Initialize the CoAp module.
89180

90181
The arguments are:
91182

92-
* `address` is the address where the CoAp module handles communication.
93-
* `port` is the port where the CoAp module listens. If not set, the default CoAp UDP port is 5683.
94-
* `service_discovery` is a Boolean argument that enables/disables service discovery. If enabled, the CoAp module will listen on the CoAp multicast address: 224.0.1.187. This is disabled by default.
183+
* `address` is the address where the CoAp module handles communication when it is a Server. If not set, the module can be used as a CoAp Client only.
184+
* `port` is the port where the CoAp Server listens. If not set, the default CoAp UDP port is 5683.
185+
* `service_discovery` is a Boolean argument that enables/disables service discovery. If enabled, the CoAp Server will listen on the CoAp multicast address: 224.0.1.187. This is disabled by default.
95186

96187
## Methods:
97188

98-
#### Coap.socket()
99-
100-
Returns with the socket assigned to the given address and port during Coap.init() (= assigned to the CoAp module).
101-
102189
#### Coap.add_resource(uri, *, media_type=-1, max_age=-1, value=0, etag=False)
103190

104-
Creates a resource object and adds it to the CoAp module to operate as a server.
191+
Creates a resource object and adds it to the CoAp Server.
105192

106193
* `uri` is the full path of the resource.
107194
* `media_type` is the media type (CoAp option: Content-Format) of the resource. If not given, no defined media type is associated with the resource.
@@ -131,9 +218,15 @@ Returns with the resource defined by `uri` argument.
131218

132219
* `uri` is the full path of the resource to be returned.
133220

134-
#### Coap.read()
221+
#### Coap.read(timeout=0)
135222

136-
Must be called when a packet is received on the socket assigned to the CoAp module. This function passes on the incoming request, whilst also composing and sending out the response if needed.
223+
Must be called peridically to process any incoming CoAp packets.
224+
225+
* `timeout` is a timeout value in milliseconds. If not set or value 0 is passed the call will be blocked forever or until a new CoAp packet arrives on the CoAp Server (if any) or on the already registered CoAp Client Sessions (if any). If the value is given it returns after the defined timeout or when a new CoAp packet arrives to the CoAp Server (if any) or to the already registered CoAp Client Sessions (if any).
226+
227+
{{% hint style="info" %}}
228+
Coap.read() is only aware of the CoAp Client Sessions created before the actual Coap.read() is called. If the `timeout` is not specified or 0, it is not safe to create additional CoAp Client Sessions after the first call to Coap.read() as it may happen that no CoAp packets arrives to the CoAp Server or to the already created CoAp Client Sessions thus the newly created CoAp Client Session will not be served as the current Coap.read() will never return.
229+
{{% /hint %}}
137230

138231
#### Coap.register_response_handler(callback)
139232

@@ -146,28 +239,58 @@ Registers a callback function which will be called when a remote CoAp Server res
146239
* `token` is the token field from the received message
147240
* `payload` is the payload of the received message
148241

149-
#### Coap.send_request(uri_host, method, *, uri_port=5683, uri_path, content_format, payload, token, include_options=true)
242+
#### Coap.new_client_session(destination, port=5683, protocol=UDP)
243+
244+
Creates a new CoAp Client Session which can be used to communicate with an external CoAp Server.
245+
246+
* `destination` is the IPv4 Address of the CoAp Server to join.
247+
* `port` is the port of the CoAp Server to join. If not set, the default CoAp UDP port 5683 is used.
248+
* `protocol` is the protocol to use to communicate with the CoAp Server. If not set the protocol UDP is used. Currently no other protocols than UDP is supported.
150249

151-
Creates and sends a request to a CoAp server.
152250

153-
* `uri_host` is the IP address of the server, included in the message as an "URI-HOST" option
251+
#### Coap.remove_client_session(destination, port=5683, protocol=UDP)
252+
253+
Removes the specified CoAp Client Session.
254+
255+
* `destination` is the IPv4 Address of the CoAp Server where this CoAp Client Session has joined.
256+
* `port` is the port of the CoAp Server where this CoAp Client Session has joined. If not set, the default CoAp UDP port 5683 is used.
257+
* `protocol` is the protocol to use to communicate with the CoAp Server where this CoAp Client Session has joined. If not set the protocol UDP is used. Currently no other protocols than UDP is supported.
258+
259+
#### Coap.get_client_sessions()
260+
261+
Returns with all the registered CoAp Client Sessions.
262+
263+
## Class Client Session
264+
265+
The CoAp Client Session class represents a Client Session in the scope of the CoAp module which can be used to communicate with an external CoAp Server. A new CoAp Client Session can only be created with the `Coap.new_client_session` function.
266+
267+
#### CoapClientSession.send_request(method, *, uri_path, content_format, payload, token, include_options=true)
268+
269+
Creates and sends a request to the external CoAp Server defined by the `destination` and `port` parameters when this CoAp Client Session was created.
270+
154271
* `method` is the method to be sent to the server, can be: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`
155-
* `uri_port` is the port of the server, included in the message as an "URI-PORT" option. By default it is 5683
156272
* `uri_path` is the full path of the resource in the server, included in the message as an "URI-PATH" option. If nothing is given the request will not have URI-PATH option.
157273
* `content_format` is the Content-Format option of the request, can be: `Coap.MEDIATYPE_TEXT_PLAIN`, `Coap.MEDIATYPE_APP_LINK_FORMAT`, `Coap.MEDIATYPE_APP_XML`, `Coap.MEDIATYPE_APP_OCTET_STREAM`, `Coap.MEDIATYPE_APP_RDF_XML`, `Coap.MEDIATYPE_APP_EXI`, `Coap.MEDIATYPE_APP_JSON`, `Coap.MEDIATYPE_APP_CBOR`. If nothing is given the request will not have Content-Format option.
158274
* `payload` is the payload of the request. If nothing is given the request will not have payload.
159275
* `token` is the token field of the request. If nothing is given the request will not have token field.
160276
* `include_options` decides whether put any options (including the ones above) into the message or not. It can be used to send special requests to servers accepting CoAp formed requests without options, e.g. to a Dish Telemetry server. By default, the options are included.
161277

162-
## Class resource
278+
#### CoapClientSession.get_details()
279+
280+
Returns with a list of elements showing internal information about this CoAP Client Session:
281+
282+
* `destination` is the IPv4 Address of the CoAp Server where this CoAp Client Session has joined.
283+
* `port` is the port of the CoAp Server where this CoAp Client Session has joined.
284+
285+
## Class CoapResource
163286

164-
The resource class represents a resource in the scope of the CoAp module when acting as a server. A new resource can only be created with the `Coap.add_resource` function.
287+
The CoapResource class represents a resource in the scope of the CoAp module when acting as a server. A new resource can only be created with the `Coap.add_resource` function.
165288

166289
#### Class methods
167290

168291
The following methods are defined in the scope of the `resource` class.
169292

170-
#### resource.add_attribute(name, value)
293+
#### CoapResource.add_attribute(name, value)
171294

172295
Adds a new attribute to the resource. Attributes are used to explain the resource during service discovery.
173296

@@ -184,14 +307,14 @@ coap-client -m get coap://<Coap-Server's address>/.well-known/core
184307

185308
{{% /hint %}}
186309

187-
#### resource.value(value)
310+
#### CoapResource.value(value)
188311

189312
Updates or fetches the value of the resource.
190313

191314
* `value` is the new value to update the current value with.
192315
If the method is called without a parameter, the current value is returned.
193316

194-
#### resource.callback(operation, enable)
317+
#### CoapResource.callback(operation, enable)
195318
To enable or disable a specific operation (GET, PUT, POST, DELETE) on the resource.
196319

197320
* `operation` is the operation to enable/disable, can be ORED of the followings: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`

0 commit comments

Comments
 (0)