How to simultaneously observe multiple resources?
WattageGuy opened this issue · 6 comments
Python version: 3.9.6 (default, Feb 3 2024, 15:58:27)
[Clang 15.0.0 (clang-1500.3.9.4)]
aiocoap version: 0.4.7
Modules missing for subsystems:
dtls: missing DTLSSocket
oscore: missing cbor2, cryptography, filelock, ge25519
linkheader: everything there
prettyprint: missing cbor2, termcolor, pygments
Python platform: darwin
Default server transports: tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Selected server transports: tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Default client transports: tcpclient:tlsclient:simple6
Selected client transports: tcpclient:tlsclient:simple6
SO_REUSEPORT available (default, selected): True, True
My lwm2m client works to observe any resource on Leshan (lwm2m server) but not to observe 2 or more. Some times it works with two but its not stable, sometimes both resources gets the same value, in most case the seconds observe also gets the first observes value but not the other way around (as seen in the pictures).
I am pretty unexperienced but I have monitored the "Sending message" in message manager and the outgoing messages seems correct, correct value to correct resource. So I dont know where or why this happens. I have also changed one line in the resource.py to get the uri_path in the request. stripped = request.copy(uri_path=request.opt.uri_path)
This is my code handling the observe:
async def handle_observe(self, request):
path = request.opt.uri_path
plen = len(path)
if plen == 1:
obs = f'observe_{path[0]}'
elif plen == 2:
obs = f'observe_{path[0]}_{path[1]}'
elif plen == 3:
obs = f'observe_{path[0]}_{path[1]}_{path[2]}'
else:
return Message(code=Code.BAD_REQUEST)
def _notifier():
self.updated_state(response=self.encoder.encode(path))
try:
obs_method = eval(obs)
cancel = request.opt.observe == '0'
_kwargs = dict(model=self.model,
path=path,
payload=request.payload,
content_format=request.opt.content_format,
cancel=cancel,
notifier=_notifier)
obs_method(None, **_kwargs)
print("Triggered observe")
return self.encoder.encode(path)
except NameError:
pass
return Message(code=Code.METHOD_NOT_ALLOWED)
async def render_get(self, request):
if request.opt.observe is not None:
log.debug(f'observe on {"/".join(request.opt.uri_path)}')
return await self.handle_observe(request)
else:
log.debug(f'read on {"/".join(request.opt.uri_path)}')
return self.handle_read(request.opt.uri_path)`
Some what related to #146
Just to avoid confusion with other issues: This is unrelated to 146 (that is about the client side). This issue here is about the CoAP server side, which for some reasons LwM2M calls the client.
To help you here I'd have to understand what you are doing, and the code you copied in is insufficient for that. Do you have a pointer to your full source code?
Okay sorry I dont know exactly what im doing, still trying to understand this CoAP stuff. Here is the project: https://github.com/WattageGuy/lwm2mclient-BLE-gateway
Any clue yet @chrysn im in a bit of hurry with this project 😅
@WattageGuy - Any progress on this issue? I'm seeing what I believe is the same anomaly. What I have noticed is that the tokens between more than one observation are being mis-assigned. Example, if I have an observation for battery_level that is using token "a1b1c1d1e1f1" and an observation for "current_time" that is using token "a2b2c2d2e2f2." It feels like updated_state() method may be mishandling this in some way. I'm thinking about creating a content message to replace the updated.state() message creation to see if that addresses the token handling.