Home Assistant and Garmin Connect – 2FA workaround

How to Use the Garmin Connect Integration in Home Assistant with Two-Factor Authentication (2FA)

If you are using the cyberjunky/home-assistant-garmin_connect custom integration for Home Assistant, you may have noticed a significant issue: the configuration flow currently does not support the entry of a two-factor authentication (2FA) code. This limitation can be frustrating for users who rely on the added security of 2FA for their Garmin Connect accounts.

Simple Workaround for 2FA Authentication Issue

Fortunately, there is a straightforward workaround that does not require modifying the integration itself. This solution takes advantage of the existing capabilities within the integration, specifically its use of the garth library.

The underlying login function already integrates the garth library, which is a major advantage. The garth library not only supports saving session tokens but also allows the integration to automatically load these tokens when needed. This means you can still use the integration with 2FA enabled on your Garmin Connect account by following a few simple steps.

Step-by-Step Guide to Using the Integration with 2FA

  1. Save Session Tokens Using Garth

    First, you need to save your session tokens with the garth library. Here’s a simple Python script to help you do this. Make sure to install the garth library first by running pip install garth.

    import garth
    from getpass import getpass
    
    email = input("Enter email address: ")
    password = getpass("Enter password: ")
    
    # If there’s MFA (multi-factor authentication), you’ll be prompted during the login process
    garth.login(email, password)
    garth.save("~/.garth")

    This script will generate and save your session tokens to ~/.garth, a hidden directory in your home directory. These tokens are valid for one year.

  2. Make Session Tokens Accessible to Home Assistant

    Depending on how you are running Home Assistant, you will need to make these tokens accessible:

    If you are running Home Assistant in Docker:

    • Copy the contents of the ~/.garth directory to a desired location.
    • Mount that directory in the Docker container. For example: /srv/docks/hass/.garth:/config/.garth.
    • Add an environment variable GARMINTOKENS that points to the path inside the container.

    If you are running Home Assistant in any other way:

    • Simply add an environment variable GARMINTOKENS that points to the directory where the tokens are stored.
  3. Configure the Integration as Usual

    Now, configure the Garmin Connect integration as you normally would if 2FA were not enabled. The saved tokens will be used automatically to authenticate your account.

  4. Enjoy Full Functionality with 2FA Enabled!

    Congratulations! You have successfully configured the integration to work with 2FA enabled, without needing to make any changes to the integration itself.

Final Thoughts

This workaround allows you to maintain the security of your Garmin Connect account while using the cyberjunky/home-assistant-garmin_connect integration in Home Assistant. The process is quick and easy, leveraging the built-in functionality of the garth library to save and manage session tokens.

If you found this guide helpful, please consider sharing it with others in the Home Assistant community!

Media ingestion snippets

rename GoPro clips according to creation dates:

for f in *.MP4; do mv -n "$f" "$(date -r "$f" +"%Y%m%d_%H%M%S").mp4"; done

change picture names according to exif data:

exiftool -r '-FileName<CreateDate' -d '%Y-%m-%d %H.%M.%S%%-c.%%le' .

make timelapse video from JPG snapshots using Intel Quick Sync:

ffmpeg -r 12 -pattern_type glob -y -i '*.jpg' -vcodec mjpeg_qsv -crf 0 "output.mp4"

make timelapse video from normal video with some motion blur using Intel QuickSync:

ffmpeg -i input.mkv -filter:v "tblend=average,framestep=2,setpts=0.1*PTS" -r 96 -b:v 30M -crf 10 -vcodec h264_qsv -an -y output.mkv

merge video files without transcoding them:

ffmpeg -safe 0 -f concat -i <(find . -type f -name '*MP4' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv

Sort pictures to camera directories:

exiftool -d '.' '-directory<${model;}/$datetimeoriginal' *.jpg

Sort pictures to Year/Month direcotires:


exiftool -d '%Y/%m' '-directory<$CreateDate' *.jpg

Homelab: Dewey

Specs:
- CPU: Intel Core i7-7700k
- Motherboard: Z270 GAMING M3 (MS-7A62)
- GPU: ASUS GeForce GTX960
- RAM: Kingston HyperX 3x8GB DDR4 2.4GHz
- Storage: 2x Corsair MP500 m.2 240G SSDs in mdadm RAID0, 1x WD Black 1TB for storage. 100GB LVM volume as writeback cache for HDD
- Fans: NOCTUA

Roles:
- Docker host
- gaming in virtual machine
- general workstation

Runs:
- ArchLinux