Quantcast
Channel: Active questions tagged zeromq - Stack Overflow
Viewing all articles
Browse latest Browse all 208

pyzmq REQ/REP with asyncio await for variable

$
0
0

I'm playing for the first time with asyncio in python and trying to combine it with ZMQ.

Basically my issue is that I have a REP/REQ system, in an async def with a function I need to await. how the value is not updated. Here's a snippet of the code to illustrate that:

#Declaring the zmq contextcontext = zmq_asyncio.Context()REP_server_django = context.socket(zmq.REP)REP_server_django.bind("tcp://*:5558")

I send this object to a class and get it back in this function

async def readsonar(self, trigger_pin, REP_server_django):        i= 0        while True:            ping_from_view = await REP_server_django.recv()  # line.1            value = await self.board.sonar_read(trigger_pin) # line.2            print(value)                                     # line.3            json_data = json.dumps(value)                    # line.4            #json_data = json.dumps(i)                       # line.4bis            REP_server_django.send(json_data.encode())       # line.5            i+=1                                             # line.6            await asyncio.sleep(1/1000)                      # line.7

the sonar_read, is using pymata_express to read an ultrasonic sensor. If I comment line.2 and line.4 I get the right value for i. If I comment line.1 and line.5 the print(value) prints the correct value from sonar_read. However, when I run it as shown here, the value is not updated.

Am I missing something?


EDIT :
Edited a type regarding the line comments. What I meant is that if I only read the sonar and print the value. It works fine. If I only .recv() and .send(json.dumps(i).encode()), it works. But if I try to send the value from the sonar. It locks to a given value which is not updated


EDIT2 : (answer to Alan Yorinks): here is the MWE, it considers what you sent regarding the declaration of zmq in the class. It is taken from the pymata_express example concurrent_tasks.py

To reproduce the error, run these two scripts in two different terminals. You will need an arduino board with Frimata_express installed. If all runs well, PART A. should only spit out the same value on the mve_req.py end. You may edit the diffrent blocks (PARTS A, B or C) to see the behaviour.

mve_rep.py

#ADAPTED FROM PYMATA EXPRESS EXAMPLE CONCURRENTTAKS#https://github.com/MrYsLab/pymata-express/blob/master/examples/concurrent_tasks.pyimport asyncioimport zmqimport jsonimport zmq.asyncio as zmq_asynciofrom pymata_express.pymata_express import PymataExpressclass ConcurrentTasks:    def __init__(self, board):        self.loop = board.get_event_loop()        self.board = board        self.ctxsync = zmq.Context()        self.context = zmq.asyncio.Context()        self.rep = self.context.socket(zmq.REP)        self.rep.bind("tcp://*:5558")        self.trigger_pin = 53        self.echo_pin = 51        loop.run_until_complete(self.async_init_and_run())    async def readsonar(self):        i = 0        while True:            #PART. A. WHAT I HOPE COULD WORK            rep_recv = await self.rep.recv()                       # line.1            value = await self.board.sonar_read(self.trigger_pin)  # line.2            print(value)                                           # line.3            json_data = json.dumps(value)                          # line.4            # json_data = json.dumps(i)                            # line.4bis            await self.rep.send(json_data.encode())                # line.5            i += 1                                                 # line.6            await asyncio.sleep(1 / 1000)                          # line.7'''            #PART. B. WORKS FINE IN UPDATING THE SONAR_RAED VALUE AND PRINTING IT            value = await self.board.sonar_read(self.trigger_pin)  # line.2            print(value)                                           # line.3            json_data = json.dumps(value)                          # line.4            i += 1                                                 # line.6            await asyncio.sleep(1 / 1000)                          # line.7''''''            #PART. C. WORKS FINE IN SENDING THE i VALUE OVER ZMQ            rep_recv = await self.rep.recv()                       # line.1            json_data = json.dumps(i)                              # line.4bis            await self.rep.send(json_data.encode())                # line.5            i += 1                                                 # line.6            await asyncio.sleep(1 / 1000)                          # line.7'''    async def async_init_and_run(self):        await self.board.set_pin_mode_sonar(self.trigger_pin, self.echo_pin)        readsonar = asyncio.create_task(self.readsonar())        await readsonar        # OTHER CREATED_TASK GO HERE, (removed them in the MVE, but they work fine)if __name__ == "__main__":    loop = asyncio.get_event_loop()    my_board = PymataExpress()    try:        ConcurrentTasks(my_board)    except (KeyboardInterrupt, RuntimeError):        loop.run_until_complete(my_board.shutdown())        print('goodbye')    finally:        loop.close()

mve_req.py

import zmqimport timeimport jsondef start_zmq():    context = zmq.Context()    REQ_django  = context.socket(zmq.REQ)    REQ_django.connect("tcp://localhost:5558")    return REQ_django, contextdef get_sonar(REQ_django):    REQ_django.send(b"server_django")    ping_from_server_django = REQ_django.recv()    return ping_from_server_django.decode()if __name__ == '__main__':    data = {"sensors":{}}    REQ_django, context = start_zmq()    while REQ_django:            data['sensors']['sonar'] = get_sonar(REQ_django)            json_data = json.dumps(data)            print(data)            #DO OTHER WORK            time.sleep(1)    REQ_django.close()    context.term()

Viewing all articles
Browse latest Browse all 208

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>