aelveborn / Wii-Scale

Turns your Wii Balance Board into a scale and presents your weight on a responsive website. Runs Linux and works on your Raspberry Pi.
http://aelveborn.github.io/Wii-Scale/
GNU General Public License v2.0
116 stars 27 forks source link

RFC: Switch back end from wiiboard.py to xwiimote and from Python to C++ #14

Closed ribbons closed 7 years ago

ribbons commented 7 years ago

Similar to #11, I have been unable to get Wii-Scale to work for me under Kubuntu 16.04. With a paired, trusted balance board the Python backend gives a bluetooth.btcommon.BluetoothError: (111, 'Connection refused'), but unlike @dm8tbr, I can't even get it to work in pairing mode.

My hypothesis is that the hid_wiimote module included in the distro jumps in and connects to the balance board as soon as it has the chance, blocking the direct connection that wiiboard.py attempts to make. Unfortunately I've been unable to properly test my hypothesis as despite my best efforts I don't seem to be able to prevent the module being loaded (I think this is because the 'hid' module automatically loads it but I may be wrong about that).

Instead I settled on a different although rather drastic solution of re-writing the Python backend in C++. This allows us to use the hid interface exposed by the kernel module. I've opted to use the xwiimote library to do most of the heavy lifting for us. I did originally look at the python xwiimote-bindings but these aren't available as a package in my distro (and I think are no-longer maintained), so ended up being more faff than switching completely to C++.

This PR is a very rough proof of concept re-write of the backend in C++ which isn't ready to merge. It just about works but needs splitting up into proper classes, having support for pairing & disconnecting added, to use the calibration parameter and have much better error handling. I'm submitting this to see if this is something that you'd be interested in adopting into this repository when I've finished it off, or if you'd prefer to stick with your current Python approach and I should just maintain this change separately in my fork?

If you do want to give the POC a try, you'll need CMake, the libxwiimote development library and headers and to recursively init the socket.io-client submodule as it also has submodules. The built wii-board binary also needs to be run as root as annoyingly it isn't possible to connect to the balance board functionality otherwise.

Delmw commented 7 years ago

Hi ribbons,

I had the same problem the first time I connected with te Wii balance board and wanted to pull data from it. It did not want to send the data to the python script and it just hanged. I did edited some code in the python script and got it to work on a raspberry PI 3B and can receive data now.

The problem I have for now is that the board(paired with bluetoothctl) does not want to connect and gives the error: bluetooth.btcommon.BluetoothError: (111, 'Connection refused').

Are you able to receive data and pair to the board?

Kind regards,

Wesley

ribbons commented 7 years ago

I had the same problem the first time I connected with te Wii balance board and wanted to pull data from it. It did not want to send the data to the python script and it just hanged. I did edited some code in the python script and got it to work on a raspberry PI 3B and can receive data now.

Do you mean that you can retrieve data from the board when it is in 'sync' mode (e.g. pressing the red button in the battery compartment)? I couldn't get the board to work for me in this mode either but it may just be I was doing things in the wrong sequence as @dm8tbr was able to get data in sync mode.

The problem I have for now is that the board(paired with bluetoothctl) does not want to connect and gives the error: bluetooth.btcommon.BluetoothError: (111, 'Connection refused').

Yes, this is the exact error I get when trying to use the existing Python code with a paired balance board.

Are you able to receive data and pair to the board?

Yes, if the board is already paired (in my case using the KDE Bluetooth applet thingy, but I believe that this uses the same bluez APIs as bluetoothctl), this code can connect to it and retrieve data.

Delmw commented 7 years ago

Do you mean that you can retrieve data from the board when it is in 'sync' mode (e.g. pressing the red button in the battery compartment)? I couldn't get the board to work for me in this mode either but it may just be I was doing things in the wrong sequence as @dm8tbr was able to get data in sync mode.

Yes I can retrieve the data when the board is in 'sync' mode, after it is connected of course.

Yes, if the board is already paired (in my case using the KDE Bluetooth applet thingy, but I believe that this uses the same bluez APIs as bluetoothctl), this code can connect to it and retrieve data.

I think it is strange that your code can connect to the board and the python code can't, because they eventually use the bluez API? My idea of where the problem lies in the way the python code connects to the board when it is synced already. So did you do any thing different in the communication protocol? Or the way to connect to the board?

Are you able to reconnect and receive data from the the board when the batteries are pulled out, re-inserted and the board is switched on with the button on the front (without using the sync button)?

ribbons commented 7 years ago

I think it is strange that your code can connect to the board and the python code can't, because they eventually use the bluez API?

The difference (as I understand it) is that the python code is attempting to connect directly to the board with bluez, whereas my code is talking to the hid_wiimote module which is automatically connecting directly to the board via bluez (and causing the python code to fail).

My idea of where the problem lies in the way the python code connects to the board when it is synced already. So did you do any thing different in the communication protocol? Or the way to connect to the board?

Yes, I'm not talking to the board directly at all, just using the XWiiMote API which then talks via the hid_wiimote kernel module.

Are you able to reconnect and receive data from the the board when the batteries are pulled out, re-inserted and the board is switched on with the button on the front (without using the sync button)?

Yes, just tried that now and it works :-)

aelveborn commented 7 years ago

Nice work @ribbons ! I'm open to the idea of rewriting the backend in C++ since I cant get the pairing working in python as your POC were able too. I do have limited spare time right now with a new born and all, so it would mean that we need the communitys help :) My only demand is for it to be able to run on an raspberry pi. So to answer your question, I would absolutly merge a C++ backend. Maybe we should continue the backend rework in another branch, what do you think about that?

ribbons commented 7 years ago

I do have limited spare time right now with a new born and all

Congratulations! Hope you are getting at least some sleep...

My only demand is for it to be able to run on an raspberry pi.

Sounds do-able :smile:.

So to answer your question, I would absolutly merge a C++ backend. Maybe we should continue the backend rework in another branch, what do you think about that?

Good plan. Unless I'm mistaken, I think you need to create the new branch before I can point this PR at it - doesn't seem to be an option for me to create a branch as part of the PR.

sahoahfoa commented 7 years ago

Wow. It took a bit of work but I got the new back end to compile! I've got a bit of free time this week so I'm gonna try and tackle the disconnect and calibration parts.

nico202 commented 7 years ago

I'm not able to connect when paired too (connection refused 111). Does work in "sync mode". I (as anyone) does not have much free time but I can program both in python and c++ (and used angular1 some time back)

ribbons commented 7 years ago

I've got a bit more time at the moment to continue tidying up my code and making it more 'production ready', so I'll close this PR for now & continue development in my fork.