MrYsLab / pymata-aio

This is the second generation PyMata client.
https://github.com/MrYsLab/pymata-aio/wiki
GNU Affero General Public License v3.0
155 stars 51 forks source link

RuntimeError: There is no current event loop in thread 'Dummy-1'. #78

Closed CuyiGuaton closed 6 years ago

CuyiGuaton commented 6 years ago

Hi, I'm getting the next error:

Traceback (most recent call last):
  File "/home/innovaengine/Documentos/pellet/Programa/controller_cortes2.py", line 679, in run
    self.NoError = self.controllino.reiniciar()
  File "/home/innovaengine/Documentos/pellet/Programa/controller_controllino.py", line 33, in reiniciar
    self.looasdp()
  File "/home/innovaengine/Documentos/pellet/Programa/controller_controllino.py", line 16, in looasdp
    self.board.set_pin_mode(count, Constants.OUTPUT)
  File "/home/innovaengine/.local/lib/python3.6/site-packages/pymata_aio/pymata3.py", line 592, in set_pin_mode
    task = asyncio.ensure_future(self.core.set_pin_mode(pin_number, pin_state, callback, cb_type))
  File "/usr/lib/python3.6/asyncio/tasks.py", line 518, in ensure_future
    loop = events.get_event_loop()
  File "/usr/lib/python3.6/asyncio/events.py", line 694, in get_event_loop
    return get_event_loop_policy().get_event_loop()
  File "/usr/lib/python3.6/asyncio/events.py", line 602, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Dummy-1'.
self.Terminar False self.madera_sesion_restante 0
Volviendo a comenzar
Se prendio esta mierda
Traceback (most recent call last):
  File "/home/innovaengine/Documentos/pellet/Programa/controller_cortes2.py", line 679, in run
    self.NoError = self.controllino.reiniciar()
  File "/home/innovaengine/Documentos/pellet/Programa/controller_controllino.py", line 33, in reiniciar
    self.looasdp()
  File "/home/innovaengine/Documentos/pellet/Programa/controller_controllino.py", line 16, in looasdp
    self.board.set_pin_mode(count, Constants.OUTPUT)
  File "/home/innovaengine/.local/lib/python3.6/site-packages/pymata_aio/pymata3.py", line 592, in set_pin_mode
    task = asyncio.ensure_future(self.core.set_pin_mode(pin_number, pin_state, callback, cb_type))
  File "/usr/lib/python3.6/asyncio/tasks.py", line 518, in ensure_future
    loop = events.get_event_loop()
  File "/usr/lib/python3.6/asyncio/events.py", line 694, in get_event_loop
    return get_event_loop_policy().get_event_loop()
  File "/usr/lib/python3.6/asyncio/events.py", line 602, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Dummy-1'.

I'm create a class called controllino, and I use the functions of the class from a pyqt5 thread, what can i do?

This is my class


from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants
from time import sleep, strftime

class controllino():
    def __init__(self):
        super(controllino, self).__init__()
        try:
            self.board = PyMata3()
        except:
            self.error_conexion()

    def looasdp(self):
        count = 2
        self.board.set_pin_mode(count, Constants.OUTPUT)
        print('pin', count)
        print("LED On")
        self.board.digital_write(count, 1)
        self.board.sleep(0.1)
        print("LED Off")
        self.board.digital_write(count, 0)
        self.board.sleep(0.1)

    #return False, error al mover la huea
    def reiniciar(self):
        self.looasdp()
        print('Reiniciando cortadora')
        sleep(2) #aquì se corta
        return True

if __name__ == "__main__":
    w = controllino()
MrYsLab commented 6 years ago

You are calling sleep in reinciar() and need to call self.board.sleep instead. This is documented here: https://github.com/MrYsLab/pymata-aio/wiki/Pymata3-Usage-Notes.

Mixing asyncio code with non-asyncio can be complicated. If your pqqt5 thread is blocking in any way, you most likely will get additional errors.

CuyiGuaton commented 6 years ago

No, it isn't work, when I try to put self.controllino.reiniciar() in the init of my thread it works, but when I put it in the run. it isn't work.


class Thread_cortar(QtCore.QThread):
    hilo_terminado = QtCore.pyqtSignal(bool)
    def __init__(self, parent=None,  controllino = None, terminar = False):
        super(Thread_cortar, self).__init__(parent)
        self.controllino = controllino
        self.controllino.reiniciar()  #it works

    def run(self):
            self.controllino.reiniciar() #Not works
            self.hilo_terminado.emit(True)

I don't know much about asyncio, but will it work if I created a thread based in asyncio instead QThread?

MrYsLab commented 6 years ago

Without seeing all of the code is difficult for me to diagnose the problem.

I modified the code you first provided. I set "count" from 2 to 6 so that I could test on my hardware. Here are my changes:

from pymata_aio.pymata3 import PyMata3
from pymata_aio.constants import Constants
from time import sleep, strftime

class controllino():
    def __init__(self):
        super(controllino, self).__init__()
        try:
            self.board = PyMata3()
        except:
            self.error_conexion()

    def looasdp(self):
        count = 6
        self.board.set_pin_mode(count, Constants.OUTPUT)
        print('pin', count)
        print("LED On")
        self.board.digital_write(count, 1)
        self.board.sleep(0.1)
        print("LED Off")
        self.board.digital_write(count, 0)
        self.board.sleep(0.1)

    # return False, error al mover la huea
    def reiniciar(self):
        self.looasdp()
        print('Reiniciando cortadora')
        self.board.sleep(2)  # aquì se corta
        return True

if __name__ == "__main__":
    w = controllino()
    while True:
        w.reiniciar()

Perhaps this article might help: https://hackernoon.com/threaded-asynchronous-magic-and-how-to-wield-it-bba9ed602c32

CuyiGuaton commented 6 years ago

Thanks from all, my error is that I'm using a sync thread to call to a async function.

MrYsLab commented 6 years ago

@ssalinasf Thank you for letting me know. There are ways of calling an async method from a sync method using the asyncio.ensure_future(name_of_async_method) construct. Here is an article that hopefully explains some of this.

It may be easier to use PyMata which is a multithreaded implementation of a Firmata client that should integrate with qt5 in a simpler way. It does not use asyncio.