Compare new / previous string state attribute and extract the difference to include in TTS Message

I have set up a Minecraft Server and have set up a TTS message when players join (and leave using reverse statement) the server using the entity / state sensor.mc_y3_survival_players_online using the following template :

{{ trigger.from_state.state|int < trigger.to_state.state|int }}

What I want to do is use the attribute identified in :

{{ state_attr(‘sensor.mc_y3_survival_players_online’, ‘players_list’)|string }}

And compare the values between from and to values so that :

  • When a player joins I can extract just the added part from the to_state value and feed that to TTS

  • When a player leaves I can extract the removed part from the from_state value and feed that to TTS

Any help would be greatly appreciated !

1 Like

Since you’re really interested in the players list attribute, trigger off of that instead of having a trigger for each direction of change.

trigger:
  - platform: state
    entity_id: sensor.mc_y3_survival_players_online
    attribute: players_list
    not_to:
      - none
      - unknown
      - unavailable
    not_from:
      - none
      - unknown
      - unavailable
condition: []
action:
  - variables:
      message: >
        {% set to = trigger.to_state.attributes.players_list %}
        {% set from = trigger.from_state.attributes.players_list %}
        {% if from > to %}
          {{ from | reject('in', to) | first }} has left the game.
        {% else %}
          {{ to | reject('in', from) | first }} has joined the game.
        {% endif %}
  - service: however you TTS
    data:
      message: "{{ message }}"
mode: queued

Thanks for the update.

Implemented what you suggested as follows :

alias: "Automation : Notification : Minecraft Survival Player Update"
description: ""
trigger:
  - platform: state
    entity_id: sensor.mc_y3_survival_players_online
    attribute: players_list
    not_to:
      - none
      - unknown
      - unavailable
    not_from:
      - none
      - unknown
      - unavailable
condition: []
action:
  - variables:
      message: >
        {% set to = trigger.to_state.attributes.players_list %} {% set from =
        trigger.from_state.attributes.players_list %} {% if from > to %}
          {{ from | reject('in', to) | first }} has left the game.
        {% else %}
          {{ to | reject('in', from) | first }} has joined the game.
        {% endif %}
  - service: tts.google_translate_say
    data:
      entity_id: media_player.bedroom_g_h
      message: "{{ message }}"
mode: queued

But when accessing the MC Server I got the following in the Logs :

2023-01-30 15:25:27.260 ERROR (MainThread) [homeassistant.helpers.event] Error while processing state change for sensor.mc_y3_survival_players_online
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 288, in _async_state_change_dispatcher
    hass.async_run_hass_job(job, event)
  File "/usr/src/homeassistant/homeassistant/core.py", line 577, in async_run_hass_job
    hassjob.target(*args)
  File "/usr/src/homeassistant/homeassistant/components/homeassistant/triggers/state.py", line 161, in state_automation_listener
    or not match_to_state(new_value)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1590, in <lambda>
    return lambda state: invert is not (state in parameter_set)
TypeError: unhashable type: 'list'
2023-01-30 15:25:27.334 ERROR (MainThread) [homeassistant.helpers.event] Error while processing state change for sensor.mc_y3_survival_players_online
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 288, in _async_state_change_dispatcher
    hass.async_run_hass_job(job, event)
  File "/usr/src/homeassistant/homeassistant/core.py", line 577, in async_run_hass_job
    hassjob.target(*args)
  File "/usr/src/homeassistant/homeassistant/components/homeassistant/triggers/state.py", line 161, in state_automation_listener
    or not match_to_state(new_value)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1590, in <lambda>
    return lambda state: invert is not (state in parameter_set)
TypeError: unhashable type: 'list'

I honestly wish I could now add some insight into this, but this is “way above my pay grade and job title” as a “Junior Associate Home Assistant Tinkerer”…

I have however I have figured out that the player_list is formatted as follows (the . (dot) value is a Geyser / Floodgate user) :

Ok, apparently me trying to be ‘smart’ was dumb… the not_to/from breaks it. I added a pair of count filters to the if statement. In testing, it helped make sure both the “leave” and “join” events were announced properly. I also added replace() functions to remove the . you mentioned.

alias: "Automation : Notification : Minecraft Survival Player Update"
description: ""
trigger:
  - platform: state
    entity_id: sensor.mc_y3_survival_players_online
    attribute: players_list
condition: []
action:
  - variables:
      message: >
        {% set to = trigger.to_state.attributes.players_list %} {% set from =
        trigger.from_state.attributes.players_list %} 
        {% if from | count > to | count %}
          {{ from | reject('in', to) | first | replace('.', ' ') }} has left the game.
        {% else %}
          {{ to | reject('in', from) | first | replace('.', ' ') }} has joined the game.
        {% endif %}
  - service: tts.google_translate_say
    data:
      entity_id: media_player.bedroom_g_h
      message: "{{ message }}"
mode: queued

I have confirmed that the above works… at least when using Alexa as the end point. I don’t use the Google say TTS services, so I can’t really help if that’s the source of any further issues.

1 Like

You sir are a genius and have made myself, a 49 year adult, and more importantly my 8 year old son happy.

I (we) now have more visibility of when his friends from his whole school year join the servers I have set up for them :+1:

1 Like

Now you just need to make it so his friends can turn his lights on and off from in-game…
Smart Home Control with MINECRAFT (Home Assistant + Mine Assistant) - YouTube (not actually sure if this still works) :slight_smile:

Ohhh dear…

My servers are papermc and I have luck perms installed too…

One for the weekend :+1: