NaitLee / Cat-Printer

Application supporting Bluetooth thermal “Cat Printers”, for everyone!
GNU General Public License v3.0
334 stars 33 forks source link

macOS: no running event loop #22

Closed andypiper closed 2 years ago

andypiper commented 2 years ago

Same as #21 I think...

Browser shows an error:

bluetoothProblemHandler@http://127.0.0.1:8095/main.js:677:20
{
    "name": "Exception",
    "details": "no running event loop"
}

Console shows:

cat-printer python3 ./server.py
Serving at http://127.0.0.1:8095/
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 64391)
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 347, in process_request
    self.finish_request(request, client_address)
  File "/Users/andypiper/Downloads/cat-printer/./server.py", line 276, in finish_request
    self.handler.__init__(request, client_address, self)
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 747, in __init__
    self.handle()
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/server.py", line 425, in handle
    self.handle_one_request()
  File "/Users/andypiper/Downloads/cat-printer/./server.py", line 82, in handle_one_request
    super().handle_one_request()
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/server.py", line 413, in handle_one_request
    method()
  File "/Users/andypiper/Downloads/cat-printer/./server.py", line 229, in do_POST
    self.handle_api()
  File "/Users/andypiper/Downloads/cat-printer/./server.py", line 190, in handle_api
    } for device in self.printer.scan()]
  File "/Users/andypiper/Downloads/cat-printer/printer.py", line 367, in scan
    scanner = BleakScanner()
  File "/Users/andypiper/Downloads/cat-printer/bleak/backends/corebluetooth/scanner.py", line 44, in __init__
    self._manager = CentralManagerDelegate.alloc().init()
  File "/Users/andypiper/Downloads/cat-printer/bleak/backends/corebluetooth/CentralManagerDelegate.py", line 61, in init
    self.event_loop = asyncio.get_running_loop()
RuntimeError: no running event loop
----------------------------------------
Exception ignored in: <CentralManagerDelegate objective-c instance 0x0>
Traceback (most recent call last):
  File "/Users/andypiper/Downloads/cat-printer/bleak/backends/corebluetooth/CentralManagerDelegate.py", line 102, in __del__
    self.central_manager.removeObserver_forKeyPath_(self, "isScanning")
AttributeError: 'CentralManagerDelegate' object has no attribute 'central_manager'
Exception ignored in: <function CentralManagerDelegate.__del__ at 0x106626670>

I've tried toggling Bluetooth off and on, but this still happens.

I do not get prompted to allow the server program access to Bluetooth, which is weird - I would expect this.

andypiper commented 2 years ago

If it helps, this code works fine, but it invokes BleakScanner with a filter directly rather than setting up a scanner object first, I don't know if this might affect the functionality.

I tried python3 ./printer.py and it also crashes with a similar result:

Cat Printer
Connecting
Traceback (most recent call last):
  File "/Users/andypiper/Downloads/cat-printer/./printer.py", line 716, in <module>
    main()
  File "/Users/andypiper/Downloads/cat-printer/./printer.py", line 696, in main
    _main()
  File "/Users/andypiper/Downloads/cat-printer/./printer.py", line 653, in _main
    printer.scan(identifier, use_result=True)
  File "/Users/andypiper/Downloads/cat-printer/./printer.py", line 367, in scan
    scanner = BleakScanner()
  File "/Users/andypiper/Downloads/cat-printer/bleak/backends/corebluetooth/scanner.py", line 44, in __init__
    self._manager = CentralManagerDelegate.alloc().init()
  File "/Users/andypiper/Downloads/cat-printer/bleak/backends/corebluetooth/CentralManagerDelegate.py", line 61, in init
    self.event_loop = asyncio.get_running_loop()
RuntimeError: no running event loop
Exception ignored in: <CentralManagerDelegate objective-c instance 0x0>
Traceback (most recent call last):
  File "/Users/andypiper/Downloads/cat-printer/bleak/backends/corebluetooth/CentralManagerDelegate.py", line 102, in __del__
    self.central_manager.removeObserver_forKeyPath_(self, "isScanning")
AttributeError: 'CentralManagerDelegate' object has no attribute 'central_manager'
Exception ignored in: <function CentralManagerDelegate.__del__ at 0x10745e3a0>
NaitLee commented 2 years ago

Hi, In newest repo state, I switched discover method to something similar as rbaron/catprinter, please test if it will work, by simply cloning the repo & run it. (in your case, you've already installed the deps so you can directly start)

I can't test those myself, 'cause I have no Mac... And (hopefully) the event-loop RuntimeError won't show, since it's just non-sense (event loop just dies when there's an (worth-to-spot) unhandled exception inside)

andypiper commented 2 years ago

It works sometimes, now. When I Refresh and scan for devices, sometimes there is an error on a particular (non-printer) device and it stops and the (GB03) printer is not in the list, but if I try again one or more times, it shows up, and then I can print. The drop-down list is showing a lot of different BLE devices as well as the printer, so I guess something is causing an error in the scan handling.

andypiper commented 2 years ago

IMG_5517 Small

Success 😸

NaitLee commented 2 years ago

Ouch! I forgot to filter non-printer devices again (first time is around 0.2.0) That's easy to fix. But I'm interested on what's the error, when being fuzzed by unrelated devices? I think we could have a workaround to avoid that.

That's enough to publish a new release :)

andypiper commented 2 years ago

Sure, so here is an example. Server says:

Exception occurred during processing of request from ('127.0.0.1', 53615)
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 347, in process_request
    self.finish_request(request, client_address)
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 308, in finish_request
    self.handler.__init__(request, client_address, self)
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 747, in __init__
    self.handle()
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/server.py", line 425, in handle
    self.handle_one_request()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 90, in handle_one_request
    super().handle_one_request()
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/server.py", line 413, in handle_one_request
    method()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 251, in do_POST
    self.handle_api()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 225, in handle_api
    self.update_printer()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 194, in update_printer
    self.printer.connect(name, address)
  File "/Users/andypiper/Development/third-party/Cat-Printer/printer.py", line 333, in connect
    self.model = Models[name]
KeyError: 'Living Room AppleTV'

BTW I cannot copy/paste from the error section on the web UI, this is really inconvenient for bug reporting! But it lists the AppleTV device in the error message.

Second time I scanned, it got stuck on a device Withings Aura 80, and finally a third time, on Unknown... by this time, my printer (GB03) shows in the list so I can select it.

Exception occurred during processing of request from ('127.0.0.1', 53830)
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 347, in process_request
    self.finish_request(request, client_address)
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 308, in finish_request
    self.handler.__init__(request, client_address, self)
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/socketserver.py", line 747, in __init__
    self.handle()
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/server.py", line 425, in handle
    self.handle_one_request()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 90, in handle_one_request
    super().handle_one_request()
  File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/server.py", line 413, in handle_one_request
    method()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 251, in do_POST
    self.handle_api()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 225, in handle_api
    self.update_printer()
  File "/Users/andypiper/Development/third-party/Cat-Printer/./server.py", line 194, in update_printer
    self.printer.connect(name, address)
  File "/Users/andypiper/Development/third-party/Cat-Printer/printer.py", line 333, in connect
    self.model = Models[name]
KeyError: 'Unknown'
----------------------------------------

So I wondered if it might be devices with spaces in the name? Or if you can be more specific about which device(s) to search for...

NaitLee commented 2 years ago

Oh sorry the sole problem is didn't filtering non-printer devices.

Only last commit have this problem, i.e. fix for macOS I will take care very soon. Thank you very much!

And, tip about looking at error message:

    self.model = Models[name]
KeyError: 'Living Room AppleTV'

As you see, this just means AppleTV wasn't found as a printer model and that's it.

NaitLee commented 2 years ago

Please try the newest 0.4.2. I'm in a hurry and didn't fix frontend error copying (it's matter of CSS).

andypiper commented 2 years ago

Yes, this is better! It now just looks for the printer and (usually) finds it, but sometimes it finds it and then gets an error (but the app still works).

Error: API Failure
    at http://127.0.0.1:8095/~every.js:691:28
    at async callApi (http://127.0.0.1:8095/~every.js:680:12)
    at async Main.set (http://127.0.0.1:8095/~every.js:1097:35)
{
    "name": "BleakError",
    "details": "Device with address B4BE32FB-7707-0593-CE92-E29B52E3E7E3 was not found"
}
NaitLee commented 2 years ago

Maybe it's Mac assigning another uuid after scanning. but I'm assuming it won't change. I'll try fix

NaitLee commented 2 years ago

Now the previous scanning result (of printers) won't persist to next page refresh. It also solves another problem I've seen. Try newest commit

NaitLee commented 2 years ago

I think it's solved, let me close :)