Skip to content

Useful import scripts

OliE edited this page May 23, 2025 · 9 revisions

MiFit 'BODY' file --> openScale CSV file

by Martin1887 see https://github.com/oliexdev/openScale/issues/669

#!/usr/bin/python

import argparse
import csv
import datetime

OPENSCALE_HEADER = '"biceps","bone","caliper1","caliper2","caliper3","calories","chest","comment","dateTime","fat","hip","lbm","muscle","neck","thigh","visceralFat","waist","water","weight"'

_MIFIT_BODY_HEADER = 'timestamp,weight,height,bmi,fatRate,bodyWaterRate,boneMass,metabolism,muscleRate,visceralFat,impedance'

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('mifit_BODY_csv_file_path')
    parser.add_argument('output_path')
    
    args = parser.parse_args()
    
    with open(args.mifit_BODY_csv_file_path, 'r') as inp:
        reader = csv.DictReader(inp)
        with open(args.output_path, 'w') as outp:
            writer = csv.DictWriter(outp, OPENSCALE_HEADER.replace('"', '').split(','))
            outp.write(f'{OPENSCALE_HEADER}\n')
            
            for line in reader:
                timestamp = int(line['timestamp'])
                output_date = datetime.datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M')
                weight = line['weight']
                writer.writerow({'dateTime': output_date, 'weight': weight})
                

Libra CSV file --> openScale CSV file

initial script by feclare see https://github.com/oliexdev/openScale/issues/28

modified script by abatula see https://github.com/oliexdev/openScale/issues/1050

#!/usr/bin/env python
"""
Simple script to transform libra csv file to openscale format
Optional argument to convert lbs to kg for correct import
Sample usage:
# Does not modify the Libra values
python libra_to_openscale.py Libra_2024-06-04.csv
# Convert Libra values from lbs to kg
python libra_to_openscale.py Libra_2024-06-04.csv lbs
"""
import sys
import csv
from dateutil.parser import parse

if len(sys.argv) < 2:
    print('Missing file to transform')
    sys.exit(1)

if (len(sys.argv) > 2) and (sys.argv[2] == 'lbs'):
    print('Converting Libra data from lbs to kg')
    weight_scalar = 0.453592
else:
    print('Leaving Libra data as-is (kg)')
    weight_scalar = 1


with open(sys.argv[1], 'r') as inputfile:
    r = csv.reader(inputfile, delimiter=";")
    lines = list(r)

with open('openScale_data_Libra.csv', 'w') as outputfile:
    writer = csv.writer(outputfile, delimiter=",")
    for w in lines:
        if len(w) == 0 or w[0].startswith("#"):
            continue
        time = w[0]
        weight_float = float(w[1]) * weight_scalar
        weight = f'{weight_float:.1f}'
        comment = w[5]
        d = parse(time)
        
        writer.writerow([d.strftime('%d.%m.%Y %H:%M'), weight, 0.0, 0.0, 0.0, 0.0, 0.0, comment])

openScale CSV file --> Garmin format

by jowlo see https://github.com/oliexdev/openScale/issues/777

#!/usr/bin/env python

"""
Simple script to transform openscale csv export files to a format accepted by garmin connect at
https://connect.garmin.com/modern/import-data

Note: When importing the language needs to be set to English, otherwise the import fails. 
Set everything to metric units and to YYYY-MM-DD date format.

If you want to compute BMI for the file give your height (im meters) as second parameter.
"""

import sys
import csv
from dateutil.parser import parse

if len(sys.argv) < 2:
    print ("Missing file to transform\n")
    sys.exit(1)

bmi = lambda size: 0;
if len(sys.argv) == 3:
    bmi = lambda weight: weight/(float(sys.argv[2])**2)
        

with open("openScale_garmin_connect_import.csv", "w") as outfile, open(sys.argv[1], "r") as infile:

    reader = csv.DictReader(infile, delimiter=",")
    writer = csv.writer(outfile, delimiter=",")
    
    outfile.write("Body\n")
    outfile.write("Date,Weight,BMI,Fat\n")
    for row in reader:
        writer.writerow([
            parse(row["dateTime"]).strftime('%Y-%m-%d'),
            row["weight"],
            bmi(float(row["weight"])),
            row["fat"]
            ])

Garmin format --> openScale CSV file

by antonmosich see https://github.com/oliexdev/openScale/issues/879

#!/usr/bin/python

import csv
import json
import datetime
import argparse

OPENSCALE_HEADER = '"biceps","bone","caliper1","caliper2","caliper3","calories","chest","comment","dateTime","fat","hip","lbm","muscle","neck","thigh","visceralFat","waist","water","weight"'

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("input")
    parser.add_argument("output")
    args = parser.parse_args()
    with open(args.input, 'r') as input_file:
        input_json = json.load(input_file)
    filtered = [entry for entry in input_json if "weight" in entry]
    with open(args.output, 'w') as output_file:
        writer = csv.DictWriter(output_file, OPENSCALE_HEADER.replace('"', '').split(','))
        output_file.write(f'{OPENSCALE_HEADER}\n')

        for entry in filtered:
            timestamp = datetime.datetime.fromisoformat(entry['weight']['timestampGMT'].ljust(23,'0'))
            weight = entry['weight']['weight'] / 1000
            writer.writerow({'dateTime': timestamp, 'weight': weight})

Google Fit CSV file --> openScale CSV file

by sainigma see https://github.com/oliexdev/openScale/issues/1040

#!/usr/bin/env python
import csv
from dateutil.parser import parse

with open('Daily activity metrics.csv', newline='') as input_csv:
  csv_reader = csv.reader(input_csv, delimiter=',')

  rows = []

  for row in csv_reader:
    rows.append(row)
  
  headers = rows[0]
  data = rows[1:]

  date_idx = headers.index('Date')
  weight_idx = headers.index('Average weight (kg)')

  with open('openscale_data.csv', 'w', newline='', encoding='utf-8') as output_csv:
    output_writer = csv.writer(output_csv, delimiter=',')

    output_writer.writerow(["dateTime", "weight"])

    for fragment in data:
      date = fragment[date_idx]
      weight = fragment[weight_idx]

      if (weight and date):
        output_writer.writerow([parse(date).strftime('%d.%m.%Y 08:00'), round(float(weight), 2)])

Apple Health --> openScale CSV file

by MoralCode see https://github.com/oliexdev/openScale/issues/731

#!/usr/bin/python

# Usage: first run your apple health export through the scripts as documented in https://github.com/markwk/qs_ledger/tree/master/apple_health
# then run this script using the BodyMass.csv from this process to get an OpenScale csv

import argparse
import csv
import datetime
from dateutil.parser import parse as parsedate

OPENSCALE_HEADER = '"biceps","bone","caliper1","caliper2","caliper3","calories","chest","comment","dateTime","fat","hip","lbm","muscle","neck","thigh","visceralFat","waist","water","weight"'
OPENSCALE_HEADER = OPENSCALE_HEADER.replace('"', '')

_APPLE_QUANTIFIEDSELF_BODYMASS_HEADER = 'sourceName,sourceVersion,device,type,unit,creationDate,startDate,endDate,value'

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('apple_bodymass_csv_file_path')
    parser.add_argument('output_path')
    
    args = parser.parse_args()
    
    with open(args.apple_bodymass_csv_file_path, 'r') as inp:
        reader = csv.DictReader(inp)
        with open(args.output_path, 'w') as outp:
            writer = csv.DictWriter(outp, OPENSCALE_HEADER.split(','))
            # outp.write(f'{OPENSCALE_HEADER}\n')
            writer.writeheader()
            
            for line in reader:
                creationDate = line['creationDate']
                output_date = parsedate(creationDate).strftime('%Y-%m-%d %H:%M')
                weight = float(line['value'])
                if line['unit'] == 'lb':
                    # convert to KG
                    weight = weight / 2.2

                comment = "Imported from Apple Health export. Data originally from "
                appname = line["sourceName"]
                # make the apple health app name a little more obvious. by default its just "health"
                if appname == "Health":
                    appname = "Apple Health"
                comment += appname + " app"
                appversion = line["sourceVersion"]
                if appversion != "":
                    comment += " version " + appversion

                writer.writerow({
                    'dateTime': output_date,
                    'weight': "{:.2f}".format(weight),
                    'comment': comment
                })

Health Coach Excel file --> openScale CSV file

by sarika-03 see https://github.com/oliexdev/openScale/issues/728

import pandas as pd
input_file = "HealthCoach.xlsx"
df = pd.read_excel(input_file)
print("Columns in Excel file:", list(df.columns))
df.columns = df.columns.str.strip()
df_openscale = pd.DataFrame()
df_openscale['date'] = pd.to_datetime(
df['Date'].astype(str) + ' ' + df['Time'].astype(str),
dayfirst=True, errors='coerce'
).dt.strftime('%Y-%m-%d %H:%M:%S')
df_openscale['weight'] = df.get('Weight (kg)', None)
df_openscale['fat'] = df.get('Body Fat (%)', None)
df_openscale['fat_top'] = df.get('Body Fat (Top %)', None)
df_openscale['fat_bottom'] = df.get('Body Fat (Bottom %)', None)
df_openscale['water'] = df.get('Water (%)', None)
df_openscale['muscle'] = df.get('Muscle (%)', None)
df_openscale['muscle_top'] = df.get('Muscle (Top %)', None)
df_openscale['muscle_bottom'] = df.get('Muscle (Bottom %)', None)
df_openscale['bone'] = df.get('Bone (kg)', None)
df_openscale['bmi'] = df.get('BMI', None)
df_openscale['bmr'] = df.get('BMR (kcal)', None)
df_openscale['amr'] = df.get('AMR (kcal)', None)
df_openscale['activity_level'] = df.get('Activity Level', None)
output_file = "openScale_ready_data.csv"
df_openscale.to_csv(output_file, index=False)
print(f"\n Conversion complete! File saved as: {output_file}")
Clone this wiki locally