blueprint:
  name: "HASPone p[8].b[all] Page 8 displays media controls"
  description: |

    ## Blueprint Version: `1.05.00`

    # Description

    Page 8 controls a selected media player with artist and track info, track back/play|pause/track forward, and volume control

    ![Preview](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/hasp_Display_Media_Control_page8.png)

    ## HASPone Page and Button reference

    <details>

    This automation is designed to work with the media controls found on page 8:

    | Page 8 |
    |--------|
    | ![Page 8](https://raw.githubusercontent.com/HASwitchPlate/HASPone/main/images/NextionUI_p8_5buttons+1slider.png) |


    </details>

  domain: automation
  input:
    haspdevice:
      name: "HASPone Device"
      description: "Select the HASPone device"
      selector:
        device:
          integration: mqtt
          manufacturer: "HASwitchPlate"
          model: "HASPone v1.0.0"
    mediaplayer:
      name: "Media Player to control"
      description: "Select a media player to control"
      selector:
        entity:
          domain: media_player
    button4attribute:
      name: "Top button attribute"
      description: "Enter the media_player attribute to show on the top-most button on the media player screen."
      default: "media_artist"
      selector:
        text:
    button5attribute:
      name: "Second button attribute"
      description: "Select the media_player attribute to show on the second-from-top button on the media player screen."
      default: "media_title"
      selector:
        text:

mode: parallel
max_exceeded: silent

variables:
  haspname: >-
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
        {{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
      {%- endif -%}
    {%- endfor -%}
  haspsensor: >-
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
        {{ entity }}
      {%- endif -%}
    {%- endfor -%}
  mediaplayer: !input mediaplayer
  button4attribute: !input button4attribute
  button5attribute: !input button5attribute
  volumeobject: '{{ "p[8].b[9]" }}'
  commandtopic: '{{ "hasp/" ~ haspname ~ "/command/" }}'
  volumecommandtopic: '{{ "hasp/" ~ haspname ~ "/command/" ~ volumeobject ~ ".val" }}'
  jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
  jsoncommandtopic: '{{ "hasp/" ~ haspname ~ "/command/json" }}'
  selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
  selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
  unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
  unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'
  selectedfg: >-
    {%- set color = namespace() -%}
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^light\..*_selected_foreground_color(?:_\d+|)$") -%}
        {%- set color.source=entity -%}
      {%- endif -%}
    {%- endfor -%}
    {%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
    {%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
    {%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
    {%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
    {{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
  selectedbg: >-
    {%- set color = namespace() -%}
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^light\..*_selected_background_color(?:_\d+|)$") -%}
        {%- set color.source=entity -%}
      {%- endif -%}
    {%- endfor -%}
    {%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
    {%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
    {%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
    {%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
    {{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
  unselectedfg: >-
    {%- set color = namespace() -%}
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^light\..*_unselected_foreground_color(?:_\d+|)$") -%}
        {%- set color.source=entity -%}
      {%- endif -%}
    {%- endfor -%}
    {%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
    {%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
    {%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
    {%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
    {{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}
  unselectedbg: >-
    {%- set color = namespace() -%}
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^light\..*_unselected_background_color(?:_\d+|)$") -%}
        {%- set color.source=entity -%}
      {%- endif -%}
    {%- endfor -%}
    {%- set brightness = state_attr(color.source, "brightness")|int(default=255) / 255 -%}
    {%- set red=(state_attr(color.source, "rgb_color")[0] * brightness)|int(default=0) -%}
    {%- set green=(state_attr(color.source, "rgb_color")[1] * brightness)|int(default=0) -%}
    {%- set blue=(state_attr(color.source, "rgb_color")[2] * brightness)|int(default=0) -%}
    {{ (red|bitwise_and(248)*256) + (green|bitwise_and(252)*8) + (blue|bitwise_and(248)/8)|int }}

  volume: "{{(state_attr(mediaplayer, 'volume_level') | float(default=0) * 255)|int}}"
  button4text: "{% if state_attr(mediaplayer, button4attribute) is none %}{% else %}{{state_attr(mediaplayer, button4attribute)|wordwrap(19, wrapstring='\\\\r')}}{% endif %}"
  button4font: "{% set attr_length = button4text|safe|length%}{% if attr_length <= 6 -%}9{% elif attr_length <= 8 %}8{% elif attr_length <= 10 %}7{% else %}6{%- endif %}"
  button5text: "{% if state_attr(mediaplayer, button5attribute) is none %}{% else %}{{state_attr(mediaplayer, button5attribute)|wordwrap(19, wrapstring='\\\\r')}}{% endif %}"
  button5font: "{% set attr_length = button5text|safe|length%}{% if attr_length <= 6 -%}9{% elif attr_length <= 8 %}8{% elif attr_length <= 10 %}7{% else %}6{%- endif %}"
  button6text: "" # prev track
  button6font: 8
  button7text: '{% if is_state(mediaplayer, "playing") %}{% else %}{% endif %}'
  button7font: 8
  button8text: "" # next track
  button8font: 8

trigger_variables:
  haspdevice: !input haspdevice
  haspname: >-
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
        {{- entity|regex_replace(find="^sensor\.", replace="", ignorecase=true)|regex_replace(find="_sensor(?:_\d+|)$", replace="", ignorecase=true) -}}
      {%- endif -%}
    {%- endfor -%}
  haspsensor: >-
    {%- for entity in device_entities(haspdevice) -%}
      {%- if entity|regex_search("^sensor\..+_sensor(?:_\d+|)$") -%}
        {{ entity }}
      {%- endif -%}
    {%- endfor -%}
  jsontopic: '{{ "hasp/" ~ haspname ~ "/state/json" }}'
  selectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedforegroundcolor/rgb" }}'
  selectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/selectedbackgroundcolor/rgb" }}'
  unselectedfgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedforegroundcolor/rgb" }}'
  unselectedbgtopic: '{{ "hasp/" ~ haspname ~ "/light/unselectedbackgroundcolor/rgb" }}'

trigger:
  - platform: state
    entity_id: !input mediaplayer
  - platform: template
    value_template: "{{ is_state(haspsensor, 'ON') }}"
  - platform: homeassistant
    event: start
  - platform: mqtt
    topic: "{{jsontopic}}"
  - platform: mqtt
    topic: "{{selectedfgtopic}}"
  - platform: mqtt
    topic: "{{selectedbgtopic}}"
  - platform: mqtt
    topic: "{{unselectedfgtopic}}"
  - platform: mqtt
    topic: "{{unselectedbgtopic}}"

condition:
  - condition: template
    value_template: "{{ is_state(haspsensor, 'ON') }}"

action:
  - choose:
      #########################################################################
      # RUN ACTIONS or Home Assistant Startup or HASPone Connect
      # Apply styles and place text
      - conditions:
          - condition: template
            value_template: >- 
              {{-
                (trigger is not defined)
              or
                (trigger.platform is none)
              or
                ((trigger.platform == 'homeassistant') and (trigger.event == 'start'))
              or
                ((trigger.platform == 'template') and (trigger.entity_id == haspsensor) and (trigger.to_state.state == 'ON'))
              -}}
        sequence:
          - service: mqtt.publish
            data:
              topic: "{{jsoncommandtopic}}"
              payload: >-
                ["p[8].b[4].pco={{selectedfg}}","p[8].b[4].bco={{selectedbg}}","p[8].b[4].pco2={{unselectedfg}}","p[8].b[4].bco2={{unselectedbg}}","p[8].b[4].font={{button4font}}","p[8].b[4].txt=\"{{button4text}}\"",
                "p[8].b[5].pco={{selectedfg}}","p[8].b[5].bco={{selectedbg}}","p[8].b[5].pco2={{unselectedfg}}","p[8].b[5].bco2={{unselectedbg}}","p[8].b[5].font={{button5font}}","p[8].b[5].txt=\"{{button5text}}\"",
                "p[8].b[6].pco={{selectedfg}}","p[8].b[6].bco={{selectedbg}}","p[8].b[6].pco2={{unselectedfg}}","p[8].b[6].bco2={{unselectedbg}}","p[8].b[6].font={{button6font}}","p[8].b[6].txt=\"{{button6text}}\"",
                "p[8].b[7].pco={{selectedfg}}","p[8].b[7].bco={{selectedbg}}","p[8].b[7].pco2={{unselectedfg}}","p[8].b[7].bco2={{unselectedbg}}","p[8].b[7].font={{button7font}}","p[8].b[7].txt=\"{{button7text}}\"",
                "p[8].b[8].pco={{selectedfg}}","p[8].b[8].bco={{selectedbg}}","p[8].b[8].pco2={{unselectedfg}}","p[8].b[8].bco2={{unselectedbg}}","p[8].b[8].font={{button8font}}","p[8].b[8].txt=\"{{button8text}}\"",
                "{{volumeobject}}.pco={{unselectedfg}}","{{volumeobject}}.bco={{unselectedbg}}","{{volumeobject}}.val={{volume}}"]

      #########################################################################
      # Update volume if it has changed state
      - conditions: # volume has changed value
          - condition: template
            value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == mediaplayer) and (trigger.from_state.attributes.volume_level != trigger.to_state.attributes.volume_level)}}'
        sequence:
          - service: mqtt.publish
            data:
              topic: "{{volumecommandtopic}}"
              payload: "{{volume}}"
      #########################################################################
      # Update button4attribute and button5attribute
      - conditions:
          - condition: template
            value_template: '{{ (trigger.platform == "state") and (trigger.entity_id == mediaplayer) }}'
        sequence:
          - service: mqtt.publish
            data:
              topic: "{{jsoncommandtopic}}"
              payload: '["p[8].b[4].font={{button4font}}","p[8].b[4].txt=\"{{button4text}}\"","p[8].b[5].font={{button5font}}","p[8].b[5].txt=\"{{button5text}}\"","p[8].b[7].txt=\"{{button7text}}\""]'

      #########################################################################
      # Handle MQTT message triggers
      - conditions:
          - condition: template
            value_template: '{{ trigger.platform == "mqtt" }}'
        sequence:
          - choose:
              #########################################################################
              # Catch incoming JSON messages
              - conditions:
                  - condition: template
                    value_template: "{{ (trigger.topic == jsontopic) and trigger.payload_json is defined }}"
                sequence:
                  - choose:
                      #########################################################################
                      # Set the volume value when the HASPone slider has moved
                      - conditions:
                          - condition: template
                            value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == volumeobject ~ ".val") }}'
                        sequence:
                          - service: media_player.volume_set
                            entity_id: !input mediaplayer
                            data:
                              volume_level: "{{trigger.payload_json.value/255}}"
                      #########################################################################
                      # Previous track button was pressed
                      - conditions:
                          - condition: template
                            value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[8].b[6]") and (trigger.payload_json.value == "ON")}}'
                        sequence:
                          - service: media_player.media_previous_track
                            entity_id: !input mediaplayer
                      #########################################################################
                      # Play/pause was pressed
                      - conditions:
                          - condition: template
                            value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[8].b[7]") and (trigger.payload_json.value == "ON")}}'
                        sequence:
                          - service: media_player.media_play_pause
                            entity_id: !input mediaplayer
                      #########################################################################
                      # Next track button was pressed
                      - conditions:
                          - condition: template
                            value_template: '{{ (trigger.topic == jsontopic) and (trigger.payload_json.event == "p[8].b[8]") and (trigger.payload_json.value == "ON")}}'
                        sequence:
                          - service: media_player.media_next_track
                            entity_id: !input mediaplayer

              #########################################################################
              # Theme: Apply selected foreground color when it changes.
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.topic == selectedfgtopic }}"
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: "{{jsoncommandtopic}}"
                      payload: >-
                        ["p[8].b[4].pco={{selectedfg}}",
                        "p[8].b[5].pco={{selectedfg}}",
                        "p[8].b[6].pco={{selectedfg}}",
                        "p[8].b[7].pco={{selectedfg}}",
                        "p[8].b[8].pco={{selectedfg}}"]
              #########################################################################
              # Theme: Apply selected background color on change
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.topic == selectedbgtopic }}"
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: "{{jsoncommandtopic}}"
                      payload: >-
                        ["p[8].b[4].bco={{selectedbg}}",
                        "p[8].b[5].bco={{selectedbg}}",
                        "p[8].b[6].bco={{selectedbg}}",
                        "p[8].b[7].bco={{selectedbg}}",
                        "p[8].b[8].bco={{selectedbg}}"]
              #########################################################################
              # Theme: Apply unselected foreground color on change
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.topic == unselectedfgtopic }}"
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: "{{jsoncommandtopic}}"
                      payload: >-
                        ["p[8].b[4].pco2={{unselectedfg}}",
                        "p[8].b[5].pco2={{unselectedfg}}",
                        "p[8].b[6].pco2={{unselectedfg}}",
                        "p[8].b[7].pco2={{unselectedfg}}",
                        "p[8].b[8].pco2={{unselectedfg}}",
                        "{{volumeobject}}.pco={{unselectedfg}}"]
              #########################################################################
              # Theme: Apply unselected background color on change
              - conditions:
                  - condition: template
                    value_template: "{{ trigger.topic == unselectedbgtopic }}"
                sequence:
                  - service: mqtt.publish
                    data:
                      topic: "{{jsoncommandtopic}}"
                      payload: >-
                        ["p[8].b[4].bco2={{unselectedbg}}",
                        "p[8].b[5].bco2={{unselectedbg}}",
                        "p[8].b[6].bco2={{unselectedbg}}",
                        "p[8].b[7].bco2={{unselectedbg}}",
                        "p[8].b[8].bco2={{unselectedbg}}",
                        "{{volumeobject}}.bco={{unselectedbg}}"]
