Talk to your Mooshimeter from Python
Dear Reader,
Many users have requested a way to talk to their Mooshimeters programatically from their computer. This blog post introduces a library and a piece of hardware that will allow you to do that.
What’s New:
On the Mooshim Github page there is now Mooshimeter-PythonAPI, a set of Python classes that will allow you to connect to, configure and receive notifications from a Mooshimeter through a BLED112. The BLED112 is available from many suppliers for roughly $20USD.
Why do I need a BLED112? Why can’t I use a regular Bluetooth 4.0 dongle?
Windows 8 is the only version of Windows supporting Bluetooth Low Energy, and the majority of Mooshimeter users are running Windows 7 or earlier. This is a real shame, OSX and many flavors of Linux have BLE support built in by now. The BLED112 provides a BLE interface but looks like a USB serial port, which is almost universally supported. So with a BLED112 you can talk to your Mooshimeter programatically from Windows, OSX or Linux.
Hardware Dependencies:
- BLED112
- Computer with USB port
Software Dependencies:
- Python 2.X
- pyserial
- If you have pip installed you can install from the command line using “python -m pip install pyserial”
- bglib
- You can install this in your Python Lib directory (usually C:/PythonXX/Lib) by copying bglib.py there, or just add bglib.py to your project
Using Mooshimeter-PythonAPI
- Download the code from the Github page.
- Plug in the BLED112 to your computer and determine the path to the port.
- On Windows you can do this through the device manager:
- On Windows you can do this through the device manager:
- Run the Example.py script with the name of the port as the argument. The script will scan for Mooshimeters, connect to the one with strongest signal, configure it and start streaming voltage and current. A sample output is below.
python Example.py COM4
Initializing BLED112 on port COM4...
Scanning...
Found 3 Mooshimeters
CE:A6:A0:39:CD:20: -39 1BC5FFA0-0200-62AB-E411-F254E005DBD4
64:B8:A0:39:CD:20: -70 1BC5FFA0-0200-62AB-E411-F254E005DBD4
CC:A6:A0:39:CD:20: -55 1BC5FFA0-0200-62AB-E411-F254E005DBD4
Connected to 20:CD:39:A0:A6:CE
Interval: 24ms
Service Groups:
0018
0118
0A18
D4DB05E0-54F2-11E4-AB62-0002A0FFC51B
1: 2800
2: 2803
3: 2A00
4: 2803
5: 2A01
6: 2803
<... list of characteristics ...>
72: 1BC5FFAB-0200-62AB-E411-F254E005DBD4
73: 2901
74: 2803
75: 1BC5FFAC-0200-62AB-E411-F254E005DBD4
76: 2901
Connection: 0
0.0000 A
-0.0001 V
Connection: 0
0.0001 A
-0.0001 V
Connection: 0
0.0001 A
-0.0001 V
Connection: 0
0.0001 A
-0.0001 V
We hope this enables new applications for you and can’t wait to see what you come up with. Thanks for reading!
~James
So to clarify… If I’m using Windows 8, and I purchase a generic Bluetooth 4.0 dongle, the hardware/drivers/operating system would work, but the API has not been designed to work with this combination? Or is there more to it than that? Ordering a single dongle off Mouser or Digikey is looking pretty expensive due to $40+ shipping on a $20 part, and I have been unable to source locally… Thanks, Anton
Hi Anton,
Your description is unfortunately correct. Even Windows 8 BLE support is strange though… you can’t scan or connect to BLE devices through their API and apparently that’s a deliberate design decision.
$40 for shipping is exorbitant though – I did a quick look around and found these guys:
http://www.glynstore.com/bluegiga-bled112-bluetooth-low-energy-usb-dongle/
I haven’t used them but they say shipping to Australia is $7.50 and NZ $6.80, much more reasonable. Hope it helps!
Hi James,
Thanks for the super-helpful response – awesome! I have ordered the part, shipping still a little expensive, but the total was only NZ$40 which is far more within my budget. Kudos for remembering that I am in New Zealand, too!
I just wish I had time to throw together a GUI for Windows, but I’m very hopeful somebody else will do that soon…
Regards,
Anton
Hi James,
First of all, awesome service from Glynstore – the BLED112 arrived today, 4.5 days after ordering.
So using that I was finally able to fire up the Mooshimeter. The response looks exactly like what you listed up until after number 76: 2901, then it just sits there. The LED goes solid on while initialising, then a brief flash, then two slow ones, then another brief flash, then nothing. Is there likely to be a setup issue on the PC, or in the Mooshimeter? How often should the readings be popping up?
Unfortunately after receiving the Mooshimeter I realised my Android phone is too old for BLE so I can’t confirm that I’ve had it working another way (not that I expect there’s anything wrong with it!).
Thanks,
Anton
Lucky you have Win8, BLE isn’t supported by the MS stack before that apparently..
https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/3b62bdbf-9a55-4c0f-becf-f4e91d4bc027/windows-8-bluetooth-le-and?forum=wdk is interesting/depressing.
I think you would have to load the relevant DLL(s) and write a wrapper.
I have started something similar for OS X (using pyobjc to interface to CoreBluetooth) – so far I can see my Mooshimeter and get the settings etc..
I haven’t gone further due to lack of time but will look at trying to write a compat shim to replace BGWrapper.
My code so far: https://gist.github.com/DanielO/c136c2d86c287f686220
This is great, thanks Daniel. Let me know if questions arise. If CoreBluetooth on OSX is the same as iOS you might try looking at the Mooshimeter iOS app for guidance, as it’s built on CoreBluetooth.
Excellent!
I’ve got a linux laptop with a BLE adapter in it (a Novena, very nice), so I’m going to write a version of BGWrapper.py that uses pygattlib instead.
Looks like the BLE stuff is a LOT easier to deal with than straight BT, woohoo!
And that’s why open-source hard/software rules! Can’t wait for pelrun.
Can’t wait for pelrun, either. My 4.3 phone refuse to talk to the meter.
Sort of. The BLE support is still a bit half-baked in linux. If I don’t want to recompile everything or write it in C then I’m having to use Bluez over d-bus, pygattlib, AND gatttool to do various parts of the implementation – each of them is supplying a critical piece that isn’t available in the other two. :P
Can’t wait for the full Bluez dbus api that came out in the latest source release to finally make it into distro packages…
Can’t wait, either. Thank you for finding out why we have to wait!
James,
Awesome job on the Mooshimeter! Thanks!
However, we’ve been working with it at our company as an alternative method of logging voltages over time, looking for power failures. However, when we pull the logs from the SD card, then run python CONV.PY file to convert the logs to CSV, all numeric values have a TAB in them. This causes the data to come into Excel(2010) as “non-numeric” text values and no amount of manipulation will convert these values back to numeric. There is a multi-step approach one of our engineers found using “Trim” and “Clean” functions in Excel, which then has to be multiplied by 1 to finally give us a numeric result we can actually CHART in Excel.
I’m looking at your example on your web page and the Excel data for voltage is numeric in your example (as seen by the right justified entries)… did you have to go thru a conversion to get the data back to numeric? Or are we doing something wrong? Why is the CONV.PY adding tabs before each numeric value? Oh, and TIME is the only field that comes over as numeric because it has no leading tab.
And, speaking of TIME, what is the 4 digit number representing and how do we convert that back into a time stamp?
Thanks again for all your hard work!
MJ
Sorry James, you can delete my previous comment about Python/Excel/Tabs in the CONV script. I found your previous reply about modifying the script and changing “,/t” to just “,” and that fixed all our problems. Sorry to waste your time.
I would still like to know about the TIME field and converting it to a time stamp.
MJ
Great! I’m glad you got that feature working.
The “time” column should be UTC time directly – or if that has not been set it should reflect the number of seconds since the Mooshimeter booted.
Thank you James. You said it should be UTC, unless it has not been set. I’ve been reading and searching – but I cannot find a way to set the clock on the MM. How do we set the UTC clock? I don’t believe mine is set, as my “Time” is coming out as ####.### not UTC.
Ah – I know what the issue is. In the iOS app it is automatically synced to the phone time, but in the Android app that feature didn’t make it through. On the to-do list, thank you!
I’ve just bought one of these https://blog.adafruit.com/2014/11/19/new-products-bluefruit-le-friend-bluetooth-low-energy-ble-4-0-nrf51822-v1-0-bluefruit-le-sniffer-bluetooth-low-energy-ble-4-0-nrf51822-v1-0/ for use as a bluetooth sniffer. The ‘standard’ code provides a bluetooth uart, apparently for the same reason – windows 7 support – that mooshimeter does.
Will this device work as the host end of the link ?
Hi Artag. Yes and no: Yes, the device you link to should be able to talk to the Mooshimeter. But no, the python code that’s already been written will not work out of the box with that unit. Thanks
Hi, now Windows 10 is out how’s the Windows BLE support looking?
Are you likely to build in support for generic Windows BT4.0 devices in the near future?
Well I bit the bullet and bought a BLED112 in the hopes of getting my Mooshimeter to talk to my PC, but I’m having no joy yet.
Windows 10 seemed to install the BLED112 drivers all automatically without any issues, I have tested by installing the BLE-GUI application and I can see my Mooshimeter.
Unfortunately running the Example.py python script keeps coming up with the error:
while ser.inWaiting(): self.parse(ord(ser.read()))
TypeError: ord() expected a character, but string of length 0 found
Sorry if I sound like a NOOB, I’m only a casual programmer and when I’m dealing with unfamiliar libraries I’m not exactly an expert at spotting the issue.
Also, far as I can tell the com port is hard-coded to com port 4? (not a user-given argument).
Hi Alex,
Hmm… regarding the TypeError: Sounds like a bug in the pyserial library or Windows 10. The correct behavior for ser.read() should be to block until a byte is available, not to just return an empty string. I think these guys encountered the same issue:
http://stackoverflow.com/questions/14236397/timeout-value-with-pyserial-is-not-working-on-windows
Can you verify your version of pyserial? How did you install it? For your reference, I just successfully tested Example.py on my system and it streams data from a meter. I’m using Windows 7, Python 2.7.9 and pyserial 2.7.
Regarding hard-coded COM4: I think you’re right, having it as a command line argument would make more sense. COM4 just happened to be the correct port on my system, that’s why I left a note in the comments above that line to that effect. If you’d like to make it a command line argument and send a PR on github I’d integrate the change.
Best
~James
Do you example for ble_cmd_sm_encrypt_start to encrypt data before write operation
Hi Prashant,
The Mooshimeter does not support encryption.
Hi James,
I got all the software components installed and waiting for the Bled112 to arrive.
I tried to run the example.py to see how it executes but I’m having some problem:
It runs until it processes line 2 in BGWrapper.py calling “import serial”.py and oit cannot find it.
tI looked allover the Mooshmeter folder and I cannot find it
Where is this file?
Thanks
John
Update
Hi all,
I installed the BLED112 and all the software components.
Since my COM4 was used, I needed to change to COM13 (in example.py, line 29).
When I try to run :”example.py”, I get the following error:
================================================================
Port error (name=’COM13′, baud=’115200′):
could not open port ‘COM13’:
WindowsError(2, ‘The system cannot find the file specified.’)
I also tried with COM4 by setting COM4 in the BLED112 port propeties, but the result is the same.
Does anyone have any suggestion to what could be the problem?
Could it be that the baudrate is too high, where can I change it?
your help is very much appreciated
Thanks,
John
Hi James,
Please disregard my previous posts.
The COM port issue was solved by simply unplugging/re-plugging the BLED112.
Now it looks like it is trying to talk to the Mooshimeter, but I’m getting an error:
Received out of order packet!
Expected: 1
Got : 216
Please let me know what could be the problem.
Thanks,
John