Plex media player time limit control automation (parental control)

Here is an automation to limit the viewing time of Plex for my kids. The idea for this automation is to prevent my kids from watching too much TV during school days. Without this automation, I have to resort to good old fashion parenting style. Now, I don’t have to manually keep track their TV time and ask them to stop. HA will do that for me. Before I get started, let me share the current scenario in my home.

  1. I have cut the cord and now fully depend on Plex for all TVs in my home.
  2. I have 2 TVs. 1 in the living room, another one in the bedroom.
  3. I am using Rasplex (installed in Raspberry Pi 2) for my TVs.
  4. I have Plex Premium subscription with multiple Home Users.
  5. All adult users have PIN protection.
  6. Kids users do not have any PIN.
  7. I have calendar component that contains all the public holidays and school holidays.

So here it goes…

First create an input booleans to tell HA whether my kid can watch TV or not.

kid_tv_watch:
  name: Can Kid Watch TV?
  initial: on

Then create a template sensor to keep track when kid is playing something on Plex.

- platform: template
  sensors:
    plexplay_kid:
      friendly_name: 'Kid is Playing Plex'
      value_template: >-
          {% if (is_state('media_player.plex_rasplexlr', 'playing') and is_state_attr('media_player.plex_rasplexlr', 'session_username', 'USERNAME')) or (is_state('media_player.plex_rasplexmb', 'playing') and is_state_attr('media_player.plex_rasplexmb', 'session_username', 'USERNAME')) %}
            on
          {% else %}
            off
          {% endif %}
      entity_id: 
        - media_player.plex_rasplexlr
        - media_player.plex_rasplexmb

Then create history_stats sensor to keep track the duration of the above sensor when its state is on

- platform: history_stats
  name: Kid Watch Plex Duration Today
  entity_id: sensor.plexplay_kid
  state: 'on'
  type: time
  start: '{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}'
  end: '{{ now() }}'

Then create the automations to control everything…

# Limit Kid's TV Time to 2 hours on school day 
- alias: 'Kid TV Limit - 2 Hours on School Day - Living Room'
  initial_state: True
  trigger:
    platform: numeric_state
    entity_id: sensor.kid_watch_plex_duration_today
    above: 2
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: media_player.plex_rasplexlr
        state: 'playing'
      - condition: template
        value_template: '{{ states.media_player.plex_rasplexlr.attributes.session_username == "USERNAME" }}'
      - condition: state
        entity_id: calendar.public_holidays
        state: 'off'
      - condition: state
        entity_id: calendar.school_holiday
        state: 'off'
      - condition: time
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
  action:
    # Tell HA Kid cannot watch TV anymore
    - service: input_boolean.turn_off
      entity_id: input_boolean.kid_tv_watch
      
    # Stop the media
    - service: media_player.media_stop
      data_template:
        entity_id: media_player.plex_rasplexlr
      
    # Talk to Kid
    - service: tts.google_say
      entity_id: media_player.vlc_living_room
      data:
        message: "You have used up your 2 hours TV time. Don't worry, you still can continue the show tomorrow. Now go do something else."


# Limit Kid's TV Time to 2 hours on school day 
- alias: 'Kid TV Limit - 2 Hours on School Day - Master Bedroom'
  initial_state: True
  trigger:
    platform: numeric_state
    entity_id: sensor.kid_watch_plex_duration_today
    above: 2
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: media_player.plex_rasplexmb
        state: 'playing'
      - condition: template
        value_template: '{{ states.media_player.plex_rasplexmb.attributes.session_username == "USERNAME" }}'
      - condition: state
        entity_id: calendar.public_holidays
        state: 'off'
      - condition: state
        entity_id: calendar.school_holiday
        state: 'off'
      - condition: time
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
  action:
    # Tell HA Kid cannot watch TV anymore
    - service: input_boolean.turn_off
      entity_id: input_boolean.kid_tv_watch
      
    # Stop the media
    - service: media_player.media_stop
      data_template:
        entity_id: media_player.plex_rasplexmb


# This will stop the media player when kid tries to play the media after his time limit is over.
- alias: 'Kid TV Limit - Over Limit'
  initial_state: True
  trigger:
    - platform: state
      entity_id: media_player.plex_rasplexlr
      to: 'playing'
    - platform: state
      entity_id: media_player.plex_rasplexmb
      to: 'playing'
  condition:
    condition: and
    conditions:
      ########################################################################
      # The session_username attribute is currently available as custom component of Plex
      ########################################################################
      - condition: template
        value_template: '{{ trigger.to_state.attributes.session_username == "USERNAME" }}'
      - condition: state
        entity_id: input_boolean.kid_tv_watch
        state: 'off'
  action:
    # Stop the media
    - service: media_player.media_stop
      data_template:
        entity_id: '{{trigger.entity_id}}'
      
    # Talk to Kid
    - service: tts.google_say
      entity_id: media_player.vlc_living_room
      data:
        message: "You are not allowed to watch the TV right now. Please try again tomorrow."


# Reset the time limit at 9am every morning.
- alias: 'Kid TV Limit - Reset Limit'
  initial_state: True
  trigger:
    platform: time
    after: '09:00:00'
  action:
    # Tell HA Kid can watch TV again
    - service: input_boolean.turn_on
      entity_id: input_boolean.kid_tv_watch


# Stop the kid from watching TV after 9pm.
- alias: 'Kid TV Limit - Bed Time'
  initial_state: True
  trigger:
    platform: time
    after: '21:00:00'
  action:
    # Tell HA Kid cannot watch TV anymore
    - service: input_boolean.turn_off
      entity_id: input_boolean.kid_tv_watch

If you want to control the input_booleans from front end, just add them to the group…

kid_tv_limit:
  name: Kid TV Limit
  entities:
    - input_boolean.kid_tv_watch

However, I must inform you that there is only one missing piece to this automation. Currently, the Plex component does not include the User ID (of the Plex user who plays the media) in its attributes. Therefore there is no way to tell who is watching the TV. Good news is the author of the Plex component; @JesseWebDotCom has said that he got the username working. So, hopefully it will be available in the next version. When it is available, I will update the above code.

UPDATE: The session_username attribute is currently available as custom component of Plex.

UPDATE 2: Revised the configuration to make use of History Statistics Sensor as per suggestion by @datamonkey. Now, the time limit is based on actual total time the media player is being played in a day.

9 Likes

Nice setup. Very clean cut-off.
Would you consider some grace period. Say if there is less than 5 minutes left in the show, let it finish?
But I think I can already see the loopholes in being generous…

Very nice!

Funny how kids (I have 3) like to “push that line” :smile:

HAHA Amazing! I don’t have kids but if I did, I’d do the same thing! Good job!

Il like that too but what if my kid watches 30 minutes. Stops and want’s to continue. Timer will run after 30 minytes …

at the moment the timer will continue to run even the kid has stopped watching the TV before the countdown ends. this is not ideal but sufficient for me because when my kid starts watching the TV, he can really glue there for hours non-stop. will consider making an actual timer that follows the state of the media player if the need arises.

I think you could use this history sensor to track how long the boolean is in the “kid is watching” state for any given day.

1 Like

Interesting. Will look into it. Thanks.

@thundergreen

Now, the time limit is based on actual total time the media player is being played in a day.

2 Likes

Hello everyone. If you are using this “project”, I’m wondering are you having any problem with it?

Recently, it doesn’t work as expected on mine. It seems the Plex component doesn’t provide the real status of the media player. For example, when my kid has stopped playing a movie, it still show the media player is playing the movie.

Hi, @masterkenobi

I have just found this thread and I really like the look of it. I shall be implementing this in order to implement your code but I think I may make a few additions. I wonder if I can add in a feature to make it time that the TV is used as we have Samsung Smart TVs. I know they have a component but I am aware they also have an API as well (although I haven’t used it).

With regards to the problem of it not behaving as expected at the moment I am wondering if PlexPi may be the way to go. I do have a panel on HASS which shows my PlexPi dashboard but I have not yet looked into the API or what can be done with it.

It is definitely something that I will be looking at though.
John

I’m sure you can but I’m not sure can it shows who is watching the TV. The main intention is to limit the kids tv time. If your smart TV supports user login, then maybe it will work.

Anyway thanks for suggesting plexpi, even though I’m not sure what is that. Are you referring to https://home-assistant.io/components/sensor.plex/ ?

My bad… mispelled

There is a custom component made for tautulli (formerly plexpy). But it didn’t says it can show who is playing the media player.

Anyway, I will try this and also the Plex sensor component later.

2 Likes

I used your instructions with the Tautulli integration, which adds a sensor for each user. The time tracking works like a charm, thanks for the instructions.