Heart Rate data length of index mismatch fix - FIT app Version
This commit is contained in:
127
fit_app.py
127
fit_app.py
@@ -27,40 +27,94 @@ from fitparse import FitFile
|
||||
|
||||
# === Helper Functions ===
|
||||
def list_fit_files():
|
||||
"""
|
||||
Listet alle .fit Files im Verzeichnis auf und sortiert sie nach Datum
|
||||
"""
|
||||
folder = './fit_files'
|
||||
files = [f for f in os.listdir(folder) if f.lower().endswith('.fit')]
|
||||
|
||||
# Extract date from the start of the filename and sort descending
|
||||
# Prüfe ob Ordner existiert
|
||||
if not os.path.exists(folder):
|
||||
print(f"Ordner {folder} existiert nicht!")
|
||||
return [{'label': 'Ordner nicht gefunden', 'value': 'NO_FOLDER'}]
|
||||
|
||||
# Hole alle .fit Files
|
||||
try:
|
||||
all_files = os.listdir(folder)
|
||||
files = [f for f in all_files if f.lower().endswith('.fit')]
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Lesen des Ordners: {e}")
|
||||
return [{'label': 'Fehler beim Lesen', 'value': 'ERROR'}]
|
||||
|
||||
def extract_date(filename):
|
||||
"""Extrahiert Datum aus Filename für Sortierung"""
|
||||
try:
|
||||
return datetime.datetime.strptime(filename[:10], '%d.%m.%Y') # Format DD.MM.YYYY
|
||||
# Versuche verschiedene Datumsformate
|
||||
return datetime.datetime.strptime(filename[:10], '%d.%m.%Y')
|
||||
except ValueError:
|
||||
try:
|
||||
return datetime.datetime.strptime(filename[:10], '%Y-%m-%d') # Format YYYY-MM-DD
|
||||
return datetime.datetime.strptime(filename[:10], '%Y-%m-%d')
|
||||
except ValueError:
|
||||
return datetime.datetime.min # Ungültige -> ans Ende
|
||||
try:
|
||||
# Versuche auch andere Formate
|
||||
return datetime.datetime.strptime(filename[:8], '%Y%m%d')
|
||||
except ValueError:
|
||||
# Wenn kein Datum erkennbar, nutze Datei-Änderungsdatum
|
||||
try:
|
||||
file_path = os.path.join(folder, filename)
|
||||
return datetime.datetime.fromtimestamp(os.path.getmtime(file_path))
|
||||
except:
|
||||
return datetime.datetime.min
|
||||
|
||||
# Sortiere Files nach Datum (neueste zuerst)
|
||||
files.sort(key=extract_date, reverse=True)
|
||||
|
||||
# Dropdown-Einträge bauen
|
||||
# Erstelle Dropdown-Optionen
|
||||
if files:
|
||||
return [{'label': f, 'value': os.path.join(folder, f)} for f in files]
|
||||
options = []
|
||||
for f in files:
|
||||
file_path = os.path.join(folder, f)
|
||||
# Zeige auch Dateigröße und Änderungsdatum an
|
||||
try:
|
||||
size_mb = os.path.getsize(file_path) / (1024 * 1024)
|
||||
mod_time = datetime.datetime.fromtimestamp(os.path.getmtime(file_path))
|
||||
label = f"{f}"
|
||||
#label = f"{f} ({size_mb:.1f}MB - {mod_time.strftime('%d.%m.%Y %H:%M')}\n)" # For debugging purpose
|
||||
except:
|
||||
label = f
|
||||
|
||||
options.append({
|
||||
'label': label,
|
||||
'value': file_path
|
||||
})
|
||||
return options
|
||||
else:
|
||||
# Dummy-Eintrag, damit es nie crasht
|
||||
return [{
|
||||
'label': 'Keine FIT-Datei gefunden',
|
||||
'value': 'NO_FILE'
|
||||
}]
|
||||
return [{'label': 'Keine .fit Dateien gefunden', 'value': 'NO_FILE'}]
|
||||
|
||||
def haversine(lon1, lat1, lon2, lat2):
|
||||
R = 6371
|
||||
"""
|
||||
Berechnet die Entfernung zwischen zwei GPS-Koordinaten in km
|
||||
"""
|
||||
R = 6371 # Erdradius in km
|
||||
dlon = radians(lon2 - lon1)
|
||||
dlat = radians(lat2 - lat1)
|
||||
a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
|
||||
return 2 * R * asin(sqrt(a))
|
||||
|
||||
def process_fit(file_path):
|
||||
"""
|
||||
Verarbeitet eine FIT-Datei und erstellt einen DataFrame
|
||||
"""
|
||||
if file_path in ['NO_FILE', 'NO_FOLDER', 'ERROR']:
|
||||
print(f"Ungültiger Dateipfad: {file_path}")
|
||||
return pd.DataFrame()
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
print(f"Datei nicht gefunden: {file_path}")
|
||||
return pd.DataFrame()
|
||||
|
||||
try:
|
||||
fit_file = FitFile(file_path)
|
||||
print(f"Verarbeite FIT-Datei: {file_path}")
|
||||
|
||||
# Sammle alle record-Daten
|
||||
records = []
|
||||
@@ -71,8 +125,13 @@ def process_fit(file_path):
|
||||
record_data[data.name] = data.value
|
||||
records.append(record_data)
|
||||
|
||||
if not records:
|
||||
print("Keine Aufzeichnungsdaten in der FIT-Datei gefunden")
|
||||
return pd.DataFrame()
|
||||
|
||||
# Erstelle DataFrame
|
||||
df = pd.DataFrame(records)
|
||||
print(f"DataFrame erstellt mit {len(df)} Zeilen und Spalten: {list(df.columns)}")
|
||||
|
||||
# Debugging: Schaue welche Spalten verfügbar sind
|
||||
print(f"Verfügbare Spalten: {df.columns.tolist()}")
|
||||
@@ -178,8 +237,8 @@ def process_fit(file_path):
|
||||
# Print the name and value of the data (and the units if it has any)
|
||||
if data.name == 'heart_rate':
|
||||
heart_rate.append(data.value)
|
||||
# hier variable neu überschrieben:
|
||||
df['heart_rate'] = heart_rate[:len(df)]
|
||||
# Hier variable neu überschrieben:
|
||||
df = safe_add_column_to_dataframe(df, 'heart_rate', heart_rate)
|
||||
# ##############
|
||||
|
||||
# MY DEBUG:
|
||||
@@ -199,6 +258,44 @@ def process_fit(file_path):
|
||||
|
||||
return df
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Verarbeiten der FIT-Datei {file_path}: {str(e)}")
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
|
||||
|
||||
def safe_add_column_to_dataframe(df, column_name, values):
|
||||
"""
|
||||
Fügt eine Spalte sicher zu einem DataFrame hinzu, auch wenn die Längen nicht übereinstimmen
|
||||
"""
|
||||
if df.empty:
|
||||
return df
|
||||
|
||||
df_len = len(df)
|
||||
values_len = len(values) if hasattr(values, '__len__') else 0
|
||||
|
||||
if values_len == df_len:
|
||||
# Perfekt - gleiche Länge
|
||||
df[column_name] = values
|
||||
elif values_len > df_len:
|
||||
# Zu viele Werte - kürze sie
|
||||
print(f"WARNUNG: {column_name} hat {values_len} Werte, DataFrame hat {df_len} Zeilen. Kürze Werte.")
|
||||
df[column_name] = values[:df_len]
|
||||
elif values_len < df_len:
|
||||
# Zu wenige Werte - fülle mit NaN auf
|
||||
print(f"WARNUNG: {column_name} hat {values_len} Werte, DataFrame hat {df_len} Zeilen. Fülle mit NaN auf.")
|
||||
extended_values = list(values) + [None] * (df_len - values_len)
|
||||
df[column_name] = extended_values
|
||||
else:
|
||||
# Keine Werte - fülle mit NaN
|
||||
print(f"WARNUNG: Keine Werte für {column_name}. Fülle mit NaN.")
|
||||
df[column_name] = [None] * df_len
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# INFO BANNER
|
||||
|
||||
Reference in New Issue
Block a user