Created
August 8, 2015 22:44
-
-
Save tewalds/86170c18ecf6f211a9bc to your computer and use it in GitHub Desktop.
Extract weights from Wii Fit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Based on http://www.kellbot.com/2010/05/extracting-graphing-wii-fit-data/ | |
# | |
# Good references: | |
# http://jansenprice.com/blog?id=9-Extracting-Data-from-Wii-Fit-Plus-Savegame-Files | |
# http://stackoverflow.com/questions/616249/wii-fit-data-format | |
# | |
# Instructions to use this: | |
# | |
# 1. Download the data from the Wii to an SD card. | |
# 2. Build tachtig, needed to decrypt the data file. | |
# $ sudo apt-get install openssl libssl-dev | |
# $ git clone git://git.infradead.org/users/segher/wii.git | |
# $ cd wii | |
# $ make | |
# Ignore the tons of warnings, just as long as it created tachtig. Double | |
# check with: | |
# $ ls -l tachtig | |
# $ cd .. | |
# 3. Install the keys needed to decrypt the file | |
# $ mkdir ~/.wii | |
# $ echo ab01b9d8e1622b08afbad84dbfc2a55d | xxd -r -p - ~/.wii/sd-key | |
# $ echo 216712e6aa1f689f95c5a22324dc6a98 | xxd -r -p - ~/.wii/sd-iv | |
# $ echo 0e65378199be4517ab06ec22451a5793 | xxd -r -p - ~/.wii/md5-blanker | |
# 4. Decrypt it: | |
# $ wii/tachtig [SD_CARD/private/wii/title/RFPE/]data.bin | |
# That should create a directory with one or more .dat files, likely either | |
# called RPHealth.dat or FitPlus0.dat | |
# 5. Extract the contents by running this script: | |
# $ chmod +x wiifit.py | |
# $ ./wiifit.py <location of .dat file> | |
# 6. Do whatever you want with the resulting WiiFit_<name>.csv file. | |
from __future__ import division | |
import csv | |
import struct | |
import string | |
import sys | |
# Path to WiiFit data file | |
file_name = sys.argv[1] if len(sys.argv) > 1 else 'RPHealth.dat' | |
# Adjust based on what the wii took off for each recording, in Kg. | |
weight_adjustment = float(sys.argv[2]) if len(sys.argv) > 2 else 0.0 | |
# Each record is 0x9271 bytes long | |
record_length = 0x9281 | |
with open(file_name, 'rb') as in_file: | |
# Iterate through each Mii. | |
for record_start in xrange(0, record_length * 100, record_length): | |
# Go to the start of the current record. | |
in_file.seek(record_start) | |
# Read the first 30 bytes (header + name). | |
line = in_file.read(30) | |
# For some reason names are stored as N a m e instead of Name. | |
# Throw away the header and any extranous spaces. | |
data = struct.unpack('<9xcxcxcxcxcxcxcxcxcxcxc', line) | |
# Condense our unpacked characters into a string. | |
wf_name = string.join(data, '').strip('\0') | |
if not wf_name: | |
break | |
print 'Found', wf_name | |
# Open a new CSV file for this person. | |
with open('WiiFit_%s.csv' % wf_name, 'w') as out_file: | |
writer = csv.writer(out_file, delimiter=',', quotechar="'", quoting=csv.QUOTE_MINIMAL) | |
writer.writerow(['Date', 'Weight', 'BMI', 'Balance']) | |
# Weight data starts 0x38a1 bytes into the record. | |
in_file.seek(record_start + 0x38a1) | |
# Loop through the record data until it starts coming up blank. | |
while True: | |
# Each line is 21 bytes. We only care about the first bit. | |
line = in_file.read(21) | |
# 4 bytes of hex-packed date followed by three sets of 2 bytes | |
# representing weight, BMI, and balance. | |
packed_date, weight, bmi, balance = struct.unpack('>i3H', line[0:10]) | |
# Unpack the date: http://stackoverflow.com/questions/719129/datetime-hex-format | |
year = packed_date >> 20 & 0x7ff | |
month = (packed_date >> 16 & 0xf) + 1 | |
day = packed_date >> 11 & 0x1f | |
hour = packed_date >> 6 & 0x1f | |
minute = packed_date & 0x3f | |
second = 0 | |
if year == 0: | |
break | |
date = '%s-%02d-%02d %02d:%02d:%02d' % (year, month, day, hour, minute, second) | |
writer.writerow([date, weight_adjustment + (weight / 10), bmi / 100, balance / 10]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment