Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Make your selection:
- **Body Composition & Weight**: 8 methods (weight tracking, body composition)
- **Goals & Achievements**: 15 methods (challenges, badges, goals)
- **Device & Technical**: 7 methods (device info, settings)
- **Gear & Equipment**: 6 methods (gear management, tracking)
- **Gear & Equipment**: 8 methods (gear management, tracking)
- **Hydration & Wellness**: 9 methods (hydration, blood pressure, menstrual)
- **System & Export**: 4 methods (reporting, logout, GraphQL)

Expand Down
64 changes: 64 additions & 0 deletions demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ def __init__(self):
"desc": "Track gear usage (total time used)",
"key": "track_gear_usage",
},
"7": {
"desc": "Add and remove gear to/from activity (interactive)",
"key": "add_and_remove_gear_to_activity",
},
},
},
"0": {
Expand Down Expand Up @@ -2394,6 +2398,63 @@ def set_gear_default_data(api: Garmin) -> None:
print(f"❌ Error setting gear default: {e}")


def add_and_remove_gear_to_activity(api: Garmin) -> None:
"""Add gear to most recent activity, then remove."""
try:
device_last_used = api.get_device_last_used()
user_profile_number = device_last_used.get("userProfileNumber")
if user_profile_number:
gear_list = api.get_gear(user_profile_number)
if gear_list:
activities = api.get_activities(0, 1)
if activities:

activity_id = activities[0].get("activityId")
activity_name = activities[0].get("activityName")
for gear in gear_list:
if gear["gearStatusName"] == "active":
break
gear_uuid = gear.get("uuid")
gear_name = gear.get("displayName", "Unknown")
if gear_uuid:
# Add gear to an activity
# Correct method signature: add_gear_to_activity(gearUUID, activity_id)
call_and_display(
api.add_gear_to_activity,
gear_uuid,
activity_id,
method_name="add_gear_to_activity",
api_call_desc=f"api.add_gear_to_activity('{gear_uuid}', {activity_id}) - Add {gear_name} to {activity_name}",
)
print("✅ Gear added successfully!")

# Wait for user to check gear, then continue
input(
"Go check Garmin to confirm, then press Enter to continue"
)

# Remove gear from an activity
# Correct method signature: remove_gear_from_activity(gearUUID, activity_id)
call_and_display(
api.remove_gear_from_activity,
gear_uuid,
activity_id,
method_name="remove_gear_from_activity",
api_call_desc=f"api.remove_gear_from_activity('{gear_uuid}', {activity_id}) - Remove {gear_name} from {activity_name}",
)
print("✅ Gear removed successfully!")
else:
print("❌ No activities found")
else:
print("❌ No gear UUID found")
else:
print("ℹ️ No gear found")
else:
print("❌ Could not get user profile number")
except Exception as e:
print(f"❌ Error adding gear: {e}")


def set_activity_name_data(api: Garmin) -> None:
"""Set activity name."""
try:
Expand Down Expand Up @@ -3295,6 +3356,9 @@ def execute_api_call(api: Garmin, key: str) -> None:
"get_gear_activities": lambda: get_gear_activities_data(api),
"set_gear_default": lambda: set_gear_default_data(api),
"track_gear_usage": lambda: track_gear_usage_data(api),
"add_and_remove_gear_to_activity": lambda: add_and_remove_gear_to_activity(
api
),
# Hydration & Wellness
"get_hydration_data": lambda: call_and_display(
api.get_hydration_data,
Expand Down
54 changes: 50 additions & 4 deletions garminconnect/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def __init__(
self.garmin_connect_upload = "/upload-service/upload"

self.garmin_connect_gear = "/gear-service/gear/filterGear"
self.garmin_connect_gear_baseurl = "/gear-service/gear/"
self.garmin_connect_gear_baseurl = "/gear-service/gear"

self.garmin_request_reload_url = "/wellness-service/wellness/epoch/request"

Expand Down Expand Up @@ -1855,13 +1855,13 @@ def get_gear(self, userProfileNumber: str) -> dict[str, Any]:
return self.connectapi(url)

def get_gear_stats(self, gearUUID: str) -> dict[str, Any]:
url = f"{self.garmin_connect_gear_baseurl}stats/{gearUUID}"
url = f"{self.garmin_connect_gear_baseurl}/stats/{gearUUID}"
logger.debug("Requesting gear stats for gearUUID %s", gearUUID)
return self.connectapi(url)

def get_gear_defaults(self, userProfileNumber: str) -> dict[str, Any]:
url = (
f"{self.garmin_connect_gear_baseurl}user/"
f"{self.garmin_connect_gear_baseurl}/user/"
f"{userProfileNumber}/activityTypes"
)
logger.debug("Requesting gear defaults for user %s", userProfileNumber)
Expand All @@ -1873,7 +1873,7 @@ def set_gear_default(
defaultGearString = "/default/true" if defaultGear else ""
method_override = "PUT" if defaultGear else "DELETE"
url = (
f"{self.garmin_connect_gear_baseurl}{gearUUID}/"
f"{self.garmin_connect_gear_baseurl}/{gearUUID}/"
f"activityType/{activityType}{defaultGearString}"
)
return self.garth.request(method_override, "connectapi", url, api=True)
Expand Down Expand Up @@ -2025,6 +2025,52 @@ def get_gear_activities(

return self.connectapi(url)

def add_gear_to_activity(
self, gearUUID: str, activity_id: int | str
) -> dict[str, Any]:
"""
Associates gear with an activity. Requires a gearUUID and an activity_id

Args:
gearUUID: UID for gear to add to activity. Findable though the get_gear function
activity_id: Integer ID for the activity to add the gear to

Returns:
Dictionary containing information for the added gear
"""

gearUUID = str(gearUUID)
activity_id = _validate_positive_integer(int(activity_id), "activity_id")

url = (
f"{self.garmin_connect_gear_baseurl}/link/{gearUUID}/activity/{activity_id}"
)
logger.debug("Linking gear %s to activity %s", gearUUID, activity_id)

return self.garth.put("connectapi", url).json()

def remove_gear_from_activity(
self, gearUUID: str, activity_id: int | str
) -> dict[str, Any]:
"""
Removes gear from an activity. Requires a gearUUID and an activity_id

Args:
gearUUID: UID for gear to remove from activity. Findable though the get_gear method.
activity_id: Integer ID for the activity to remove the gear from

Returns:
Dictionary containing information about the removed gear
"""

gearUUID = str(gearUUID)
activity_id = _validate_positive_integer(int(activity_id), "activity_id")

url = f"{self.garmin_connect_gear_baseurl}/unlink/{gearUUID}/activity/{activity_id}"
logger.debug("Unlinking gear %s from activity %s", gearUUID, activity_id)

return self.garth.put("connectapi", url).json()

def get_user_profile(self) -> dict[str, Any]:
"""Get all users settings."""

Expand Down
Loading