HaxoGreen is just around the corner, taking place july 28th to july 31st. This years edition is already the fifth of this small but very cozy and nice hacker camp, and unfortunately there are no tickets left.
More info can be found on the Wiki, also there's @HaxoGreen and #haxogreen on Twitter as well as #haxogreen on IRC on Freenode. If you're an attendee and want to give a talk or hold a workshop there's still time! There are some slots just waiting for you. Contact Orga at hello[_at_]haxogreen.lu and go for it :)
Some years ago I bought a Beurer BM58 blood pressure meter to occasionally, well, measure blood pressure. (Though I can think of a lot of neat things to build out of it shall it break...) It came with a USB connection, has two users and can save up to 60 records (per user?). It also came with a Windows only software.
Being a Linux person I've asked the Internet if anybody else maybe has published something to read out data from it. I've come across two projects, none of which are compatible unfortunately. There are at least two versions of the Beurer BM58 out there:
- Connected via some USB-Serial bridge (ttyUSB)
- Connected as HID device, lsusb: "0c45:7406 Microdia"
I've got the latter one. The projects I've found are:
- BPM can work with the usb-serial Beurer BM58
- Atbrask has written something for another meter (Beurer BM65 via usb/serial)
Atbrask also has written up some information about the USB protocol that device uses, some parts are similar to what my device does.
So I needed to reverse the protocol and throw together some python. I've fired up a VirtualBox with M.S. Windows as well as Wireshark with the usbmon module. Never having done much lower level USB stuff this was all new for me, but it was fun and I learned something on the way yay!
You can find the code on GitHub. It uses PyUSB, you'll need a 1.x version. Debian Jessie comes with 0.4.3, but 1.0.0 is available in the backports.
What it does:
- Read out all records of user 1 (U1), accessible as nested dict.
- If run directly print out the records
What it currently does not:
- Read out user 2 (U2) data. I've forgot this when making the USB dumps and didn't need it. I'll add it eventually.
- Put the data into any kind of (csv maybe) file, database or anything like that.
- Everything else. Actually, it doesn't do much at all.
Protocol and stuff
The protocol is straight forward. First the device wants to be initialized some bytes and send you its identifier. Every USB request is 8 bytes long, and usually only the first byte in the request changes while the rest is padded with 0xf4. For example to initialize you'd send:
0xaa 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xa4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xa5 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xa6 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xa7 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4
The device will respond with the identifier "Andon Blood Pressure Meter KD"
You can then ask it for the number of records in storage:
0xa2 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4
Which it will answer with, well, the number. Then you can download the records by incrementing the second byte, starting at 0x01. For example first three records:
0xa3 0x01 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xa3 0x02 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xa3 0x03 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4
It'll answer with something like this, converted to decimal:
100 55 60 2 3 26 38 8
For some reason the systolic and diastolic values need to be incremented by 25. They are the first two, so incremented the record looks like this:
125 80 60 2 3 16 38 8
|8||8||No Idea ;)|
I don't know yet what the 8. byte is, the value was always 8. Maybe the year? I don't even know if you can set a year on the device, but most probably yes. My clock wasn't correct and I didn't bother to much so I can't correlate.
Then you can close the device cleanly:
0xf7 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf6 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4 0xf4
What's important is that de device only stays active for like 30 seconds after it's plugged in. I didn't realize this and it took me much time debugging why my USB connection wouldn't work. Always times out, but it also times out if you send the wrong stuff to it. Also if you don't terminate cleanly you can't requery the device without replugging.
Keep that in mind.
So, what's left to do?
- Add user 2 support
- Write records to some file. CSV probably
- Write records to DB? SQLite comes to mind
- For me most important: Throw records at Graphite
Graph ALL the things!
For a number of reasons, I've recently set up a new OpenPGP key, and will be transitioning away from my old one. Here's the transition statement, signed by both my old and my new key:
(Or download it here)
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Fri, 19 Feb 2016 21:43 I've recently created a new OpenPGP Key and will transition away from my old one. The old key will continue to be valid for some time, but I prefer all future correspondence to come to the new one. This message is signed by both keys to certify the transition. the old key was: pub 4096R/95FC3745 2013-07-05 [expires: 2016-07-04] Key fingerprint = A705 94BE CF58 8F1D 2E26 DF1D 8EE8 3FC9 95FC 3745 The new key is: pub 4096R/7A9C3BD7 2016-02-10 [expires: 2018-02-09] Key fingerprint = 2EEC EFE3 C2FC 5E65 FF11 8B88 6835 1706 7A9C 3BD7 To fetch the key from my web site and import it: wget -q -O- https://muling.lu/muling_gpg.asc | gpg --import - Or fetch it from a public key server: gpg --recv-key 0x7A9C3BD7 If you already know my old key, you can now verify that the new key is signed by the old one: gpg --check-sigs 0x7A9C3BD7 If you don't already know my old key, or you just want to be double extra paranoid, you can check the fingerprint against the one above: gpg --fingerprint 7A9C3BD7 Please let me know if there is any trouble, and sorry for the inconvenience. Regards, Muling -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJWx43PAAoJEI7oP8mV/DdFKIsQALLy9QSuoz/2Qd+Xe+ClDzag j1GxthYLb4aWXW/R6DCNW5jsrbUl5WazKZzCFA3+OQMTSB1WG/2Z0OcMHu2DvzD9 ZT2sq/84FFNxW1+pEdUkFVlXEnBHzR9KMmFmMj6LlLbZzZzp48CLoWth7qJWQBcD 7HWI2N/elnyGSZ5v4HAg9yzuC59EdEn32qgcv5o/PEd3g787596GxrWq8BexgFp1 q+gC+Z+8x/1hrVDuCaB55YthALbRvxkh31iX/1CvV0kvhRJlqDiJGZ6VIo9ltezx 8yaqyDIfY1p6kdNLVfOgbMltvHR7mw6UzdCBvyh9S5q3QQsgzVT/7QJ9BVbkVoqQ BWCyOnW4SW+HzQH2TdBpKmPuY7tLQtmefZBLrGvc1nJeGishyVYrnwD9F6kPVZz6 26gjWWWkdoEW24G9eO0fZedX6y124OwV8h0DtYZHYfGTr6Mh3a6ZzoXjxHoIPITh jvJVS75DBgcRjw5OzXPrieqnJytjRS3Yn0ipksILS+349HrHkoq/o1Da6musoafn km0jWhmr6ew/yjDCMOVbJoc+5ECNzEbplOmAnmO28EdgPntX8Ttr5TZsdNf+n6kS niGO4PZsvLSKQ0V9goQWEE+XaLzmMUByy0+yi2usTO7OgJqFFO6xINrJb4XoOdYv rjdwZAJ9dE5/ofo0Q91riQIcBAEBAgAGBQJWx43PAAoJEK1YjnSh3hMFKIsP+wRC KYccpf194+brtbgeFx+gan0zd24bwBgagNw9QIEca2oyWcMpFSv5/DOXoi3q7eTa 1N2nEhBd2g24lJc600x4GMMyz/PRCEWGmJyYtByMx/dETJOYFpCjiTYdvK8/ijHs 4HexAGg5rx3Pts0cEs36ETVSBOaOhjNUwsp2ykaVYhtD1Cfsm3wK+8UgeonGk283 I2aSiPWfiybNXF7LbvAtRYKzepKinubgNOrrT7m/buqVAleA6q/2BZIvrULNpY80 Eg8ZqFj9fdxnXqhSY6ngQ2/28EiUvSF04doq43ZuVnonyMlwyAhpKvBStNj0SwCc nDsip0vYMafioVB9frCtNT8SRPw2nNzUBN0fCsBEgFAzFBeUV6zt6mECp3S7j9TF xVMMB1Xubhxqn09WwU1ed989l9mjqDi/IXIrh9wB7LN2F62Qg/F9HU4q64voSftg kRHEYB8syMnt1PFV6AJhx+uFsHZC1A5zB32tIv6uIMCtnSbIlVEVyFZeDLi9ZnoV j3BDrYr3LRxY1XTcPFfpUmEFdDxAGo9dsG9UHRyrlGYY3WX2yNleWjZEvBC/pNvU PQQawsWFduyVNMWfgxnOOKcoanSs8Kh4zIrUAt2eYQ7be2RKyIQY1BCXXBBoRr8f 90X877AL6o2/o13lgp7GzkAOnUJZgeeVrb7IH2ok =tpch -----END PGP SIGNATURE-----
When I first got into Graphite I was totally flashed by it. It seemed to be the holy grail in gathering all kinds of data about basically anything. Later when Grafana came along things got really nice looking too. Together these are incredibly powerful and gathering data was never easier, just send a data point with a name and timestamp and you're set. I use it for performance data of many systems as well as things like power usage, temperature, voltage, audio signal amplitude or RSSI of radio signals. Make sure to check them out if you've got some love for graphs and data.
As I've got an rTorrent instance (together with ruTorrent) why not push the data to Graphite too. I've written rTorrent-graphite (GitHub), a Python script which uses the XML-RPC API (_not_ SCGI, at least not yet) to extract some basic data such as:
- Used bandwidth up/down, including set limits
- Used memory, including set limits
- Number of torrents total, complete & incomplete
- Bytes remaining & done
- Number of peers, seeds, accounted
I'll probably add some other metrics later, and/or switch from XML-RPC to WSGI since that's a more direct way to speak with rTorrent. The image below shows how it can look like in Grafana. Graph ALL the things!
8 years ago I've started blogging, not regularly or frequent or anything, but still.. Back then I opted for WordPress, it was fast to set up and I didn't know yet if I even liked blogging at all. Actually I only started because I had that server & domain anyway and wanted to throw something on the web server, not because I wanted to get into blogging...
I've wanted to switch to something static as well as start writing in English for years, but never got around to. So today is the day, yay! There are quite a few static blog engines out there to choose from, I took Pelican. Important for me were:
- Markdown or reStructuredText support
- Content as flat files so I can write posts in vim
- Git repo for content, theme and stuff
- Easy templating - I don't like web design stuff (as you probably can see), so I want to do as little of that as possible
- Optional dynamic commenting system
- Atom or RSS feed
I may add some commenting system later though, unfortunately this means that the site won't be totally static anymore since it needs to store and read these comments somewhere. I don't want to use any third party system such as Disqus so there's no way around that, oh well.
Kay, technical stuff done. So this blog will be about nerdy things in general, a place where I can document projects I do and stuff like that. Definitely more technical oriented than my old German blog. The old WordPress based one is still online by the way, but I'll take it down (or export to something static) eventually.
Well then, hope I can fill this place with some life!