Add Mi Fitness sleep and workout sync support

This commit is contained in:
binglua committed 2026-06-21 11:45:53 +00:00
1 parent 6440121d67
commit 62be8dfc2b
3 files changed
+230 -4

No files matched your search

+61 -1
View File
@@ -132,6 +132,34 @@ async def list_tools() -> list[Tool]:
"required": ["start_date", "end_date"],
},
),
Tool(
name="query_sleep",
description="Query sleep sessions",
inputSchema={
"type": "object",
"properties": {
"start_date": {"type": "string"},
"end_date": {"type": "string"},
"include_naps": {"type": "boolean"},
},
"required": ["start_date", "end_date"],
},
),
Tool(
name="query_workouts",
description="Query workouts",
inputSchema={
"type": "object",
"properties": {
"start_date": {"type": "string"},
"end_date": {"type": "string"},
"activity_types": {"type": "array", "items": {"type": "string"}},
"min_duration": {"type": "integer"},
"min_distance_km": {"type": "number"},
},
"required": ["start_date", "end_date"],
},
),
Tool(
name="get_data_coverage",
description="Get data coverage",
@@ -160,6 +188,10 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
result = await _handle_query_heart_rate(arguments)
elif name == "query_body_measurements":
result = await _handle_query_body_measurements(arguments)
elif name == "query_sleep":
result = await _handle_query_sleep(arguments)
elif name == "query_workouts":
result = await _handle_query_workouts(arguments)
elif name == "get_data_coverage":
result = await _handle_get_data_coverage(arguments)
else:
@@ -181,7 +213,7 @@ async def _handle_get_connection_status() -> dict:
last_sync = None
available_types = []
if db:
for data_type in ["daily_activity", "heart_rate", "body_measurements"]:
for data_type in ["daily_activity", "heart_rate", "body_measurements", "sleep", "workouts"]:
state = db.get_sync_state(data_type)
if state and state.get("last_sync_at"):
available_types.append(data_type)
@@ -304,6 +336,34 @@ async def _handle_query_body_measurements(arguments: dict) -> dict:
).model_dump()
async def _handle_query_sleep(arguments: dict) -> dict:
if not query_service:
return {"status": "error", "error": "Query service not initialized"}
sessions = query_service.get_sleep_sessions(
start_date=arguments["start_date"],
end_date=arguments["end_date"],
include_naps=arguments.get("include_naps", True),
)
return QueryResponse(
status="ok", source="cache", data={"sessions": sessions, "count": len(sessions)}
).model_dump()
async def _handle_query_workouts(arguments: dict) -> dict:
if not query_service:
return {"status": "error", "error": "Query service not initialized"}
workouts = query_service.get_workouts(
start_date=arguments["start_date"],
end_date=arguments["end_date"],
activity_types=arguments.get("activity_types"),
min_duration=arguments.get("min_duration"),
min_distance_km=arguments.get("min_distance_km"),
)
return QueryResponse(
status="ok", source="cache", data={"workouts": workouts, "count": len(workouts)}
).model_dump()
async def _handle_get_data_coverage(arguments: dict) -> dict:
if not query_service:
return {"status": "error", "error": "Query service not initialized"}