Make Plex API call on media change and parse XML/JSON

Hi! I’ve been working hard trying to figure out how to change a projector’s lens memory with Home Assistant.

I have multiple steps completed, but the last one is problematic.

Here are the steps I’m trying to achieve:

  1. :white_check_mark: Generate an aspectRatios.json file based on the crop data parsed from images in each media file.
  2. :white_check_mark: Write an automation triggered by Plex’s media state changing.
  3. :no_entry: Make an API call to Plex to get the file system location using the content ID in state attributes. :white_check_mark: I can make the call, but I don’t know how to do it in Home Assistant nor how to get the Plex token from the integration.
  4. :white_check_mark: Change projector lens memory setting with virtual remote based on the selected aspect ratio.

As you can see, the one thing I need help with is the hardest.

I need to:

  1. Figure out how to make an API call to my Plex server in an automation. This returns XML.
  2. Read a JSON file shared over the network or stored locally and pass the file location as the first object key, then get the aspect ratio property off it.

If I can do those two things, I’ll have this entire system finally figured out!

Could someone help me figure out how to handle XML, JSON, and API calls?

I eventually figured this out. I used Python scripts to do it.

:no_entry: Python Scripts

Using python_script didn’t work because it’s too restrictive. I like the API better, but you can’t make fetch requests nor read files.

:white_check_mark: Shell Command → Python Scripts

My solution was to use shell_command in configuration.yaml like so:

shell_command:
  get_aspect_ratio: >
    python3 /config/scripts/get_aspect_ratio.py --aspect_ratio_calculations_file_path "{{ aspect_ratio_calculations_file_path }}" --aspect_ratio_calculation_type {{ aspect_ratio_calculation_type }} --plex_media_file_path "{{ plex_media_file_path }}"

  get_plex_media_file_path: >
    python3 /config/scripts/get_plex_media_file_path.py --plex_server_domain "{{ plex_server_domain }}" --plex_server_port "{{ plex_server_port }}" --plex_token "{{ plex_token }}" --rating_key "{{ rating_key }}"

I made two Python scripts because they’re doing two separate tasks. It’s separation-of-concerns. It means you could write your own code to grab the media path or write your own aspect ratio lookup code.

Args

Then in Python, I grabbed those args using argparse like so:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--plex_server_domain', required=True)
parser.add_argument('--plex_server_port', required=False, default='32400')
parser.add_argument('--plex_token', required=True)
parser.add_argument('--rating_key', required=True)

args = parser.parse_args()

print(args.plex_server_domain)

Automation

Lastly, I used them in an automation like so:

action: shell_command.get_plex_media_file_path
data:
  plex_server_domain: storeman.octen
  plex_server_port: 32400
  plex_token: REDACTED
  rating_key: "{{ trigger.to_state.attributes.media_content_id }}"
response_variable: plex_media_file_path
enabled: true

You can take that plex_media_file_path variable and pass it around now. Whatever’s printed goes into that variable.