Page 1 of 1

HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 1:38 pm
by raspberrypiguy1
Hello all,

I am using a Python library called cwiid in order to get data from a Wiimote and I want to make it into a tutorial! I have just coded a fairly big program that also gets accelerometer data from the Wiimote... It all works however periodically through the program I get warnings that say this:

Code: Select all

Received unexpected write report
They do not affect the program but I think that they do not look pretty and I can't be doing a tutorial with them in!

How on earth do I get Python to ignore them?!

Here is my program:

Code: Select all

 This program utilises the cwiid Python library in order to get input over bluetooth from a wiimote.
# The following lines of code demonstrate many of the features realted to wiimotes, such as capturing button presses and rumbling the controller.
# Whilst cwiid does have support for accelerometer data, it is not very well documented and thus hard to implement efficiently!

# Coded by The Raspberry Pi Guy. Work based on some of Matt Hawkin's!

import cwiid, time

button_delay = 0.1

print 'Please press buttons 1 + 2 on your Wiimote now ...'
time.sleep(1)

# This code attempts to connect to your Wiimote and if it fails the program quits
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print "Cannot connect to your Wiimote. Run again and make sure you are holding buttons 1 + 2!"
  quit()

print 'Wiimote connection established!\n'
print 'Go ahead and press some buttons\n'
print 'Press PLUS and MINUS together to disconnect and quit.\n'

wii.rpt_mode = cwiid.RPT_BTN

while True:

  buttons = wii.state['buttons']

  # Detects whether + and - are held down and if they are it quits the program
  if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
    print '\nClosing connection ...'
    # NOTE: This is how you RUMBLE the Wiimote
    wii.rumble = 1
    time.sleep(1)
    wii.rumble = 0
    exit(wii)

  # The following code detects whether any of the Wiimotes buttons have been pressed and then prints a statement to the screen!
  if (buttons & cwiid.BTN_LEFT):
    print 'Left pressed'
    time.sleep(button_delay)

  if(buttons & cwiid.BTN_RIGHT):
    print 'Right pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_UP):
    print 'Up pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_DOWN):
    print 'Down pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_1):
    print 'Button 1 pressed'    
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_2):
    print 'Button 2 pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_A):
    print 'Button A pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_B):
    print 'Button B pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_HOME):
    wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC
    check = 0
    while check == 0:
      print(wii.state['acc'])
      time.sleep(0.01)
      check = (buttons & cwiid.BTN_HOME)
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_MINUS):
    print 'Minus Button pressed'
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_PLUS):
    print 'Plus Button pressed'
    time.sleep(button_delay)

Thanks,

The Raspberry Pi Guy

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 2:18 pm
by raspberrypiguy1
Forgot to add that you will get a special thanks in my upcoming tutorial as well!

Thanks

The Raspberry Pi Guy

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 2:41 pm
by DougieLawson
raspberrypiguy1 wrote:
How on earth do I get Python to ignore them?!
The normal way to get Python to ignore stuff is to wrap a try: except: block round it.

Code: Select all

try:
  something that may not work goes here
except:
  pass
It's difficult to suggest debugging options without more detail.
1. What line of your code gets the exception?
2. Where does the cwiid library come from? Have you checked its bug lists?

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 2:43 pm
by asb
The problem here is that the cwiid library (the underlying C implementation) has a whole bunch of calls to a function that prints error messages. By default, this will print to standard error (for background see http://en.wikipedia.org/wiki/Standard_s ... 8stderr.29 - every process has stdin, stdout, and stderr). There is a function in that C library to change the function used to handle these errors/warnings, but it's not exposed to the cwiid python binding as far as I can see. Therefore, the simplest workaround is to just redirect stderr to /dev/null so anything printed to stderr will be dropped. This can be done with e.g.

Code: Select all

python mycode.py 2>/dev/null
. The disadvantage is you can't use stderr yourself for anything.

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 2:45 pm
by asb
DougieLawson wrote:
raspberrypiguy1 wrote:
How on earth do I get Python to ignore them?!
The normal way to get Python to ignore stuff is to wrap a try: except: block round it.

Code: Select all

try:
  something that may not work goes here
except:
  pass
The problem is it's not an exception, it's just the library being noisy. It might be possible to get a handle to the cwiid.so that was loaded when you do import cwiid and call cwiid_set_err(NULL) using ctypes or cffi, but otherwise just dumping all stderr gets the job done.

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 2:49 pm
by raspberrypiguy1
As Alex said, unfortunately it is not an exception - otherwise it would have been a piece of cake to get round!

It is all working now thanks to python mycode.py 2>/dev/null!

Cheers fellas,

Matt

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 2:50 pm
by ZacharyIgielman
asb wrote:
DougieLawson wrote:
raspberrypiguy1 wrote:
How on earth do I get Python to ignore them?!
The normal way to get Python to ignore stuff is to wrap a try: except: block round it.

Code: Select all

try:
  something that may not work goes here
except:
  pass
The problem is it's not an exception, it's just the library being noisy. It might be possible to get a handle to the cwiid.so that was loaded when you do import cwiid and call cwiid_set_err(NULL) using ctypes or cffi, but otherwise just dumping all stderr gets the job done.
Is there anything he can't solve? How about a competition, 'find something that Alex doesn't know or can't fix'? The prize is being smarter than the genius! Well done Alex (again)!

Re: HELP! I need Python to ignore this little error!

Posted: Sun Mar 02, 2014 3:26 pm
by jojopi
asb wrote:It might be possible to get a handle to the cwiid.so that was loaded when you do import cwiid and call cwiid_set_err(NULL) using ctypes or cffi, but otherwise just dumping all stderr gets the job done.
How about:

Code: Select all

import sys, os
sys.stderr = os.fdopen(os.dup(2), "w")
os.dup2(os.open("/dev/null", os.O_WRONLY), 2)
Now as far as POSIX is concerned, stderr (by definition, file descriptor 2) is /dev/null. But Python still has a working sys.stderr object, so you do not lose any error messages from the interpreter.

(I am not able to check this against cwiid. Any child processes will inherit the POSIX stderr, not the Python one.)