Skip to content

Custom-card "Washer"

Washer Dryer off

Small layout when the washer, dryer or dishwasher is turned off (ulm_custom_card_washer_power === "off"). It shows the content of the idle label variable (ulm_custom_card_washer_label_idle)

Washer Dryer Ready

When the washer, dryer or dishwasher is turned on the possible (job) stages of machine become visible (In this example the dryer has no different (job) stages so the stages remain closed)

Washer Dryer Remote Control

When the washer, dryer or dishwasher is set to smart control (ulm_custom_card_washer_remote_control === "true"), you can start the machine from you app, or you can start it using automation. The buttons will reflect this stage change.

Washer Dryer Timer

When you want to start the washer, dryer or dishwasher at a specific time (through automation) you can turn on the timer (press the icon and the ulm_custom_card_washer_delayed_start === "on") and set the time to start (use the up and down buttons of click on the time to set ulm_custom_card_washer_delayed_starttime (Time only)). It shows the content of the configuration label variable (ulm_custom_card_washer_label_configuring).

Washer Dryer Running

When the washer, dryer or dishwasher is running you can use the running label variable (ulm_custom_card_washer_label_running) to show the remaining time. The dryer can't be paused so the button is disabled.

!! Attention !!

This custom card is build based on a Samsung Washer and Dryer and based on the SmartThings Custom integration (installable using HACS: https://github.com/veista/smartthings). Other washer, dryers or dishwasher could work with this custom card, but might require some work. This card is highly configurable, but for the machine state you might need a template sensors to support the same terminology (run, pause, stop).

Credits

  • Author: Cruguah - 2023
  • Version: 1.0.2

  • Thanks to rphlwnk for sharing his code of his washing machine card.

  • Thanks to dougmaitelli for sharing his experience and configuration of his washing machine (LG SmartThinQ).

Changelog

1.0.2 Added an extra variable ulm_custom_card_washer_machine_stop_state to support more washers (LG SmartThinQ) #1268. Thanks to dougmaitelli for pointing out this issue.
1.0.1 Small bug fix resolving issue #1230.
1.0.0 Initial release.

Usage

Example for Samsung SmartThings:

- type: "custom:button-card"
  template: "custom_card_haven_washer"
  variables:
    ulm_custom_card_washer_power: switch.washingmachine_switch
    ulm_custom_card_washer_remote_control: sensor.washingmachine_remote_control
    ulm_custom_card_washer_machine_state: sensor.washingmachine_machine_state
    ulm_custom_card_washer_job_state: sensor.washingmachine_job_state
    ulm_custom_card_washer_job_states:
      state1:
        name: "weightSensing"
        icon: "mdi:scale"
      state2:
        name: "wash"
        icon: "mdi:waves"
      state3:
        name: "rinse"
        icon: "mdi:water"
      state4:
        name: "spin"
        icon: "mdi:fan"
    ulm_custom_card_washer_delayed_start: input_boolean.washingmachine_latest_start
    ulm_custom_card_washer_delayed_starttime: input_datetime.washingmachine_latest_starttime
    ulm_custom_card_washer_label_idle: >
      [[[
        var name = states["sensor.washingmachine_energy"].attributes.friendly_name;
        var value = states["sensor.washingmachine_energy"].state;
        var measurement = states["sensor.washingmachine_energy"].attributes.unit_of_measurement;
        return name + " • " + value + " " + measurement;
      ]]]
    ulm_custom_card_washer_label_running: "[[[ return states["sensor.washer_remaining_time"].state; ]]]"
    ulm_custom_card_washer_label_configuring: >
      [[[
          var name = states["sensor.washer_actual_starttime"].attributes.friendly_name;
          var time = states["sensor.washer_actual_starttime"].attributes.display_time;
          return name + " • " + time;
      ]]]
    ulm_custom_card_washer_start_action:
      action: "call-service"
      service: switch.turn_on
      service_data:
        entity_id: switch.washer_run_action
    ulm_custom_card_washer_pause_action:
      action: "call-service"
      service: switch.turn_on
      service_data:
        entity_id: switch.washer_pause_action
    ulm_custom_card_washer_stop_action:
      action: "call-service"
      service: switch.turn_on
      service_data:
        entity_id: switch.washer_stop_action

Example for LG SmartThinQ

- type: "custom:button-card"
  template: "custom_card_haven_washer"
  variables:
    ulm_custom_card_washer_power: sensor.washer
    ulm_custom_card_washer_machine_state: sensor.washer_run_state
    ulm_custom_card_washer_machine_stop_state: "-"
    ulm_custom_card_washer_job_state: sensor.washer_run_state
    ulm_custom_card_washer_job_states:
      state1:
        name: "Detecting"
        icon: "mdi:scale"
      state2:
        name: "Washing"
        icon: "mdi:waves"
      state3:
        name: "Rinsing"
        icon: "mdi:water"
      state4:
        name: "Spin"
        icon: "mdi:fan"
    ulm_custom_card_washer_label_idle: >
      [[[
        return "-";
      ]]]
    ulm_custom_card_washer_label_running: >
      [[[
        return states["sensor.washer_remaining_time"].state;
      ]]]
    ulm_custom_card_washer_label_configuring: >
      [[[
          var name = states["sensor.washer_initial_time"].attributes.friendly_name;
          var time = states["sensor.washer_initial_time"].attributes.display_time;
          return name + " • " + time;
      ]]]

Requirements

An integration that will support your washer, dryer, dishwasher or any other machine with job stages that you want to monitor.

When using a Samsung Washing machine or Dryer that integrates with SmartThings, a default integration is available in Home Assistant and this custom card works with this integration. One thing missing in the default SmartThings integration is the ability to see is remote control is enabled. A custom integration is available which extends the sensors with a remote control sensor. Integration from HACS: "SmartThings Custom" (https://github.com/veista/smartthings) from veista.

When using a LG Washing machine or Dryer or Dishwasher that integrates with LG SmartThinQ, a custom integration is available from HACS: "LG ThinQ Devices integration for HomeAssistant" (https://github.com/ollo69/ha-smartthinq-sensors) that works with this integration.

Additional: Show the remaining time

If you want to show the remaining time of your wash you can use the following template sensor to calculate duration.

template:
  - sensor:
      - unique_id: washer_remaining_time
        name: "Remaining Time"
        state: >-
          {% set rem_h = (as_timestamp(states.sensor.washer_completion_time.state) - as_timestamp(now())) | timestamp_custom("%-H", false) %}
          {% set rem_m = (as_timestamp(states.sensor.washer_completion_time.state) - as_timestamp(now())) | timestamp_custom("%-M", false) %}
          {% if int(rem_h) > 0.9 %} {{ rem_h }} hour(s) and {{ rem_m }} minute(s)  {% else %} {{ rem_m }} minute(s) {% endif %}

Additional: Control the washing machine of dryer remotely

Starting, pausing or stopping the washer or dryer is currently not supported by the Samsung SmartThings integration. To use the start, pause, and stop buttons, you can create command line switches, which can initiate the corresponding action. When creating a command-line switch, you need to replace the following items:

Variable Explanation
action this should be run, pause or stop
deviceId The id of your device (guid)
PAT Token The same PAT Token you"ve created during the installation of the SmartThings integration

For every action you need to create an other command-line switch.

Please ensure the capabilities of you machine before creating command-line switches.

switch:
  - platform: command_line
    switches:
      washer_run_action:
        unique_id: switch.washer_<action>_action
        value_template: >
          {% if is_state("switch.washer_<action>_action", "on") %}
            false
          {% endif %}
        command_on: >
          curl --location --request POST "https://api.smartthings.com/v1/devices/<deviceId>/commands" --header "authorization: Bearer <PAT Token>" --header  "Content-Type: text/plain" --data-raw "[{"capability":"washerOperatingState","command":"setMachineState","arguments":["<action>"]}]"

Variables

Main parameters

Variable Example Required Explanation
ulm_custom_card_washer_power switch.washingmachine_switch yes Is the washing machine or dryer turned on?
ulm_custom_card_washer_remote_control sensor.washingmachine_remote_control no Can we control the washing machine or dryer remotely
ulm_custom_card_washer_machine_state sensor.washingmachine_machine_state no What is the current state of washing machine or dryer: none, run or pause
ulm_custom_card_washer_machine_stop_state "stop" no What is the value for the stop stage of the ulm_custom_card_washer_machine_state
ulm_custom_card_washer_job_state sensor.washingmachine_job_state no What is the current step in the program, weightSensing, wash, rinse, spin or drying
ulm_custom_card_washer_job_states List of maximum 5 states (name and icon) to show as job states no Define the job states of the washing machine of dryer (or any other machine that you wanna use)
ulm_custom_card_washer_delayed_start input_boolean.washingmachine_latest_start no Turn on the ability to start the washing machine of dryer at a specific time
ulm_custom_card_washer_delayed_starttime input_datetime.washingmachine_latest_starttime no What time should the washing machine or dryer start
ulm_custom_card_washer_label_idle Any text, for example the number of runs no What label to show when the washing machine or dryer is idle
ulm_custom_card_washer_label_running Any text, for example the remaining time of the current program no What label to show when the washing machine or dryer is running
ulm_custom_card_washer_label_configuring Any text, for example, the end result of all the settings no What label to show when the washing machine or dryer is being configured
ulm_custom_card_washer_start_action A collection of setting to change a value or start an action no This contains all the parameters to start the washing machine or dryer (See the next table)
ulm_custom_card_washer_pause_action A collection of setting to change a value or start an action no This contains all the parameters to pause the washing machine or dryer (See the next table)
ulm_custom_card_washer_stop_action A collection of setting to change a value or start an action no This contains all the parameters to stop the washing machine or dryer (See the next table)

Parameters specific for the start, pause and stop of the washing machine of dryer

Variable Example Required Explanation
action none no Action to perform (more-info, toggle, call-service, navigate, url, none) Default: none
entity entity_id no Entity id to call the action on
navigation_path The navigation path for the call no Path to navigate to (e.g., /lovelace/0/) when action defined as navigate
url_path The url path for the call no Path to navigate to (e.g., https://www.home-assistant.io) when action defined as url
service The service to call the action on no Service to call (e.g., media_player.media_play_pause) when action defined as call-service
service_data The service_data to call the action on no Service data to include (e.g., entity_id: media_player.bedroom) when action defined as call-service
Template Code
custom_card_haven_washer.yaml
---
custom_card_haven_washer:
  template:
    - "ulm_language_variables"
    - "ulm_translation_engine"
  variables:
    ulm_custom_card_washer_power:
    ulm_custom_card_washer_remote_control:
    ulm_custom_card_washer_machine_state:
    ulm_custom_card_washer_machine_stop_state: "stop"
    ulm_custom_card_washer_job_state:
    ulm_custom_card_washer_label_idle: "idle"
    ulm_custom_card_washer_label_configuring: "configure"
    ulm_custom_card_washer_label_running: "run"
    ulm_custom_card_washer_delayed_start:
    ulm_custom_card_washer_delayed_starttime:
    ulm_custom_card_washer_job_states:
      state1:
        name:
        icon:
      state2:
        name:
        icon:
      state3:
        name:
        icon:
      state4:
        name:
        icon:
      state5:
        name:
        icon:
    ulm_custom_card_washer_start_action:
      action: "none"
    ulm_custom_card_washer_pause_action:
      action: "none"
    ulm_custom_card_washer_stop_action:
      action: "none"
  triggers_update: "all"
  show_icon: false
  show_label: false
  show_name: false
  show_state: false
  show_last_changed: false
  show_entity_picture: false
  styles:
    grid:
      - grid-template-areas: >
          [[[
            var rows = ["\'row1\'"];

            if (!!variables.ulm_custom_card_washer_job_state) {
              rows.push("\'row2\'");
            }

            if (!!variables.ulm_custom_card_washer_remote_control) {
              rows.push("\'row3\'");
            }

            if (!!variables.ulm_custom_card_washer_delayed_start
              && !!variables.ulm_custom_card_washer_delayed_starttime) {
              rows.push("\'row4\'");
            }

            return rows.join(" ");
          ]]]
      - grid-template-columns: "1fr"
      - grid-template-rows: "min-content"
      - row-gap: "0px"
    card:
      - border-radius: "var(--border-radius)"
      - box-shadow: "var(--box-shadow)"
      - padding: "12px"
    custom_fields:
      row2:
        - display: >
            [[[
              return (!!variables.ulm_custom_card_washer_job_state
                && !!variables.ulm_custom_card_washer_power
                && !!states[variables.ulm_custom_card_washer_power]?.state
                && states[variables.ulm_custom_card_washer_power].state === "on") ? "block" : "none";
            ]]]
      row3:
        - display: >
            [[[
              return (!!variables.ulm_custom_card_washer_power
                && !!states[variables.ulm_custom_card_washer_power]?.state
                && states[variables.ulm_custom_card_washer_power].state === "on"
                && !!variables.ulm_custom_card_washer_remote_control
                && !!states[variables.ulm_custom_card_washer_remote_control]?.state
                && states[variables.ulm_custom_card_washer_remote_control].state === "true") ? "block" : "none";
            ]]]
      row4:
        - display: >
            [[[
              return (!!variables.ulm_custom_card_washer_power
                && !!states[variables.ulm_custom_card_washer_power]?.state
                && states[variables.ulm_custom_card_washer_power].state === "on"
                && !!variables.ulm_custom_card_washer_remote_control
                && !!states[variables.ulm_custom_card_washer_remote_control]?.state
                && states[variables.ulm_custom_card_washer_remote_control].state === "true"
                && !!variables.ulm_custom_card_washer_delayed_start
                && !!states[variables.ulm_custom_card_washer_delayed_start]?.state
                && states[variables.ulm_custom_card_washer_delayed_start].state === "on"
                && !!variables.ulm_custom_card_washer_delayed_starttime) ? "block" : "none";
            ]]]
  custom_fields:
    row1:
      card:
        type: "custom:button-card"
        template:
          - "icon_info"
          - "blue_on"
        tap_action:
          action: "more-info"
        label: >
          [[[
            if (!!variables.ulm_custom_card_washer_power
              && !!states[variables.ulm_custom_card_washer_power]?.state
              && states[variables.ulm_custom_card_washer_power].state === "on") {
              if (!!variables.ulm_custom_card_washer_machine_state
                && !!states[variables.ulm_custom_card_washer_machine_state]?.state
                && states[variables.ulm_custom_card_washer_machine_state].state !== variables.ulm_custom_card_washer_machine_stop_state) {
                if (!!variables.ulm_custom_card_washer_label_running) {
                  return variables.ulm_custom_card_washer_label_running;
                }
              } else {
                if (!!variables.ulm_custom_card_washer_remote_control
                  && !!states[variables.ulm_custom_card_washer_remote_control]?.state
                  && states[variables.ulm_custom_card_washer_remote_control].state === "true"
                  && !!variables.ulm_custom_card_washer_delayed_start
                  && !!states[variables.ulm_custom_card_washer_delayed_start]?.state
                  && states[variables.ulm_custom_card_washer_delayed_start].state === "on") {
                  if (!!variables.ulm_custom_card_washer_label_configuring) {
                    return variables.ulm_custom_card_washer_label_configuring;
                  }
                } else {
                  if (!!variables.ulm_custom_card_washer_label_idle) {
                    return variables.ulm_custom_card_washer_label_idle;
                  }
                }
              }
            } else {
              if (!!variables.ulm_custom_card_washer_label_idle) {
                return variables.ulm_custom_card_washer_label_idle;
              }
            }

            var label = states[variables.ulm_custom_card_washer_power].state;
            label = variables["ulm_" + label] ?? label;

            if (!!variables.ulm_custom_card_washer_machine_state
              && !!states[variables.ulm_custom_card_washer_machine_state]
              && !!states[variables.ulm_custom_card_washer_machine_state].state) {
              var state = states[variables.ulm_custom_card_washer_machine_state].state;
              label += " • " + variables["ulm_" + state] ?? state;
            }

            return label;
          ]]]
        entity: "[[[ return variables.ulm_custom_card_washer_power; ]]]"
        styles:
          card:
            - box-shadow: "none"
            - padding: "0px"
    row2:
      card:
        type: "custom:button-card"
        styles:
          img_cell:
            - justify-items: "center"
          grid:
            - grid-template-areas: >
                [[[
                  var items = [];

                  if (!!variables.ulm_custom_card_washer_job_states) {
                    if (!!variables.ulm_custom_card_washer_job_states.state1?.name
                      && !!variables.ulm_custom_card_washer_job_states.state1?.icon) {
                      items.push("item1");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state2?.name
                      && !!variables.ulm_custom_card_washer_job_states.state2?.icon) {
                      items.push("item2");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state3?.name
                      && !!variables.ulm_custom_card_washer_job_states.state3?.icon) {
                      items.push("item3");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state4?.name
                      && !!variables.ulm_custom_card_washer_job_states.state4?.icon) {
                      items.push("item4");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state5?.name
                      && !!variables.ulm_custom_card_washer_job_states.state5?.icon) {
                      items.push("item5");
                    }
                  }

                  return "\'" + items.join(" ") + "\'";
                ]]]
            - grid-template-columns: >
                [[[
                  var columns = [];

                  if (!!variables.ulm_custom_card_washer_job_states) {
                    if (!!variables.ulm_custom_card_washer_job_states.state1?.name
                      && !!variables.ulm_custom_card_washer_job_states.state1?.icon) {
                      columns.push("1fr");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state2?.name
                      && !!variables.ulm_custom_card_washer_job_states.state2?.icon) {
                      columns.push("1fr");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state3?.name
                      && !!variables.ulm_custom_card_washer_job_states.state3?.icon) {
                      columns.push("1fr");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state4?.name
                      && !!variables.ulm_custom_card_washer_job_states.state4?.icon) {
                      columns.push("1fr");
                    }
                    if (!!variables.ulm_custom_card_washer_job_states.state5?.name
                      && !!variables.ulm_custom_card_washer_job_states.state5?.icon) {
                      columns.push("1fr");
                    }
                  }

                  return columns.join(" ");
                ]]]
            - grid-template-rows: "min-content"
            - column-gap: "7px"
            - justify-items: "center"
          card:
            - padding: "0px"
            - box-shadow: "none"
            - margin-top: "12px"
            - border-radius: "var(--border-radius)"
            - pointer-events: "none"
            - background-color: "rgba(var(--color-theme), 0.05)"
            - justify-items: "center"
          custom_fields:
            item1:
              - display: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_job_states?.state1
                      && !!variables.ulm_custom_card_washer_job_states.state1.name
                      && !!variables.ulm_custom_card_washer_job_states.state1.icon) ? "block" : "none";
                  ]]]
            item2:
              - display: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_job_states?.state2
                      && !!variables.ulm_custom_card_washer_job_states.state2.name
                      && !!variables.ulm_custom_card_washer_job_states.state2.icon) ? "block" : "none";
                  ]]]
            item3:
              - display: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_job_states?.state3
                      && !!variables.ulm_custom_card_washer_job_states.state3.name
                      && !!variables.ulm_custom_card_washer_job_states.state3.icon) ? "block" : "none";
                  ]]]
            item4:
              - display: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_job_states?.state4
                      && !!variables.ulm_custom_card_washer_job_states.state4.name
                      && !!variables.ulm_custom_card_washer_job_states.state4.icon) ? "block" : "none";
                  ]]]
            item5:
              - display: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_job_states?.state5
                      && !!variables.ulm_custom_card_washer_job_states.state5.name
                      && !!variables.ulm_custom_card_washer_job_states.state5.icon) ? "block" : "none";
                  ]]]
        custom_fields:
          item1:
            card:
              type: "custom:button-card"
              template: "custom_card_haven_washer_state"
              icon: >
                [[[
                  return (!!variables.ulm_custom_card_washer_job_states?.state1
                    && !!variables.ulm_custom_card_washer_job_states.state1.icon)
                      ? variables.ulm_custom_card_washer_job_states.state1.icon
                      : "mdi:cancel";
                ]]]
              state:
                - value: >
                    [[[
                      return (!!variables.ulm_custom_card_washer_job_states?.state1
                        && !!variables.ulm_custom_card_washer_job_states.state1.name)
                          ? variables.ulm_custom_card_washer_job_states.state1.name
                          : "unknown";
                    ]]]
                  styles:
                    icon:
                      - transform: "scale(1.2)"
                      - color: "black"
                    card:
                      - background-color: "white"
              entity: "[[[ return variables.ulm_custom_card_washer_job_state; ]]]"
          item2:
            card:
              type: "custom:button-card"
              template: "custom_card_haven_washer_state"
              icon: >
                [[[
                  return (!!variables.ulm_custom_card_washer_job_states?.state2
                    && !!variables.ulm_custom_card_washer_job_states.state2.icon)
                      ? variables.ulm_custom_card_washer_job_states.state2.icon
                      : "mdi:cancel";
                ]]]
              state:
                - value: >
                    [[[
                      return (!!variables.ulm_custom_card_washer_job_states?.state2
                        && !!variables.ulm_custom_card_washer_job_states.state2.name)
                          ? variables.ulm_custom_card_washer_job_states.state2.name
                          : "unknown";
                    ]]]
                  styles:
                    icon:
                      - transform: "scale(1.2)"
                      - color: "black"
                    card:
                      - background-color: "white"
              entity: "[[[ return variables.ulm_custom_card_washer_job_state; ]]]"
          item3:
            card:
              type: "custom:button-card"
              template: "custom_card_haven_washer_state"
              icon: >
                [[[
                  return (!!variables.ulm_custom_card_washer_job_states?.state3
                    && !!variables.ulm_custom_card_washer_job_states.state3.icon)
                      ? variables.ulm_custom_card_washer_job_states.state3.icon
                      : "mdi:cancel";
                ]]]
              state:
                - value: >
                    [[[
                      return (!!variables.ulm_custom_card_washer_job_states?.state3
                        && !!variables.ulm_custom_card_washer_job_states.state3.name)
                          ? variables.ulm_custom_card_washer_job_states.state3.name
                          : "unknown";
                    ]]]
                  styles:
                    icon:
                      - transform: "scale(1.2)"
                      - color: "black"
                    card:
                      - background-color: "white"
              entity: "[[[ return variables.ulm_custom_card_washer_job_state; ]]]"
          item4:
            card:
              type: "custom:button-card"
              template: "custom_card_haven_washer_state"
              icon: >
                [[[
                  return (!!variables.ulm_custom_card_washer_job_states?.state4
                    && !!variables.ulm_custom_card_washer_job_states.state4.icon)
                      ? variables.ulm_custom_card_washer_job_states.state4.icon
                      : "mdi:cancel";
                ]]]
              state:
                - value: >
                    [[[
                      return (!!variables.ulm_custom_card_washer_job_states?.state4
                        && !!variables.ulm_custom_card_washer_job_states.state4.name)
                          ? variables.ulm_custom_card_washer_job_states.state4.name
                          : "unknown";
                    ]]]
                  styles:
                    icon:
                      - transform: "scale(1.2)"
                      - color: "black"
                    card:
                      - background-color: "white"
              entity: "[[[ return variables.ulm_custom_card_washer_job_state; ]]]"
          item5:
            card:
              type: "custom:button-card"
              template: "custom_card_haven_washer_state"
              icon: >
                [[[
                  return (!!variables.ulm_custom_card_washer_job_states?.state5
                    && !!variables.ulm_custom_card_washer_job_states.state5.icon)
                      ? variables.ulm_custom_card_washer_job_states.state5.icon
                      : "mdi:cancel";
                ]]]
              state:
                - value: >
                    [[[
                      return (!!variables.ulm_custom_card_washer_job_states?.state5
                        && !!variables.ulm_custom_card_washer_job_states.state5.name)
                          ? variables.ulm_custom_card_washer_job_states.state5.name
                          : "unknown";
                    ]]]
                  styles:
                    icon:
                      - transform: "scale(1.2)"
                      - color: "black"
                    card:
                      - background-color: "white"
              entity: "[[[ return variables.ulm_custom_card_washer_job_state ]]]"
    row3:
      card:
        type: "custom:button-card"
        template: >
          [[[
            return !!variables.ulm_custom_card_washer_delayed_start
              && !!variables.ulm_custom_card_washer_delayed_starttime ? "list_3_items" : "list_2_items";
          ]]]
        styles:
          card:
            - padding: "0px"
            - margin-top: "12px"
          custom_fields:
            item3:
              - display: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_delayed_start
                      && !!variables.ulm_custom_card_washer_delayed_starttime) ? "block" : "none";
                  ]]]
        custom_fields:
          item1:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              tap_action:
                action: >
                  [[[
                    if (!!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state) {
                      return variables.ulm_custom_card_washer_start_action?.action ?? "none";
                    } else {
                      return variables.ulm_custom_card_washer_pause_action?.action ?? "none";
                    }
                  ]]]
                entity: "[[[ return variables.ulm_custom_card_washer_start_action.entity; ]]]"
                navigation_path: >
                  [[[
                    return (!!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state)
                      ? variables.ulm_custom_card_washer_start_action?.navigation_path
                      : variables.ulm_custom_card_washer_pause_action?.navigation_path;
                  ]]]
                url_path: >
                  [[[
                    return (!!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state)
                      ? variables.ulm_custom_card_washer_start_action?.url_path
                      : variables.ulm_custom_card_washer_pause_action?.url_path;
                  ]]]
                service: >
                  [[[
                    return (!!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state)
                      ? variables.ulm_custom_card_washer_start_action?.service
                      :  variables.ulm_custom_card_washer_pause_action?.service;
                  ]]]
                service_data: >
                  [[[
                    return (!!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state)
                      ? variables.ulm_custom_card_washer_start_action?.service_data
                      : variables.ulm_custom_card_washer_pause_action?.service_data;
                  ]]]
              icon: >
                [[[
                  return (!!states[variables.ulm_custom_card_washer_machine_state]?.state
                    && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state) ? "mdi:play" : "mdi:pause";
                ]]]
              state:
                - operator: "template"
                  value: >
                    [[[
                      return ((states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state
                          && (!variables.ulm_custom_card_washer_start_action?.action
                            || (!!variables.ulm_custom_card_washer_start_action?.action
                              && variables.ulm_custom_card_washer_start_action.action === "none")))
                        || (states[variables.ulm_custom_card_washer_machine_state].state !== variables.ulm_custom_card_washer_machine_stop_state
                          && (!variables.ulm_custom_card_washer_pause_action?.action
                            || (!!variables.ulm_custom_card_washer_pause_action?.action
                              && variables.ulm_custom_card_washer_pause_action.action === "none"))));
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.2)"
              entity: "[[[ return variables.ulm_custom_card_washer_machine_state; ]]]"
          item2:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              tap_action:
                action: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_machine_state
                      && !!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state !== variables.ulm_custom_card_washer_machine_stop_state
                      && variables.ulm_custom_card_washer_stop_action?.action) ?? "none";
                  ]]]
                entity: "[[[ return variables.ulm_custom_card_washer_stop_action.entity; ]]]"
                navigation_path: "[[[ return variables.ulm_custom_card_washer_stop_action.navigation_path; ]]]"
                url_path: "[[[ return variables.ulm_custom_card_washer_stop_action.url_path; ]]]"
                service: "[[[ return variables.ulm_custom_card_washer_stop_action.service; ]]]"
                service_data: "[[[ return variables.ulm_custom_card_washer_stop_action.service_data; ]]]"
              icon: "mdi:stop"
              state:
                - operator: "template"
                  value: >
                    [[[
                      return ((!!variables.ulm_custom_card_washer_machine_state
                          && !!states[variables.ulm_custom_card_washer_machine_state]?.state
                          && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state)
                        || !variables.ulm_custom_card_washer_stop_action?.action
                        || (!!variables.ulm_custom_card_washer_stop_action?.action
                          && variables.ulm_custom_card_washer_stop_action.action === "none"));
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.2)"
              entity: "[[[ return variables.ulm_custom_card_washer_machine_state ]]]"
          item3:
            card:
              type: "custom:button-card"
              template:
                - "widget_icon"
                - "green_on"
              tap_action:
                action: >
                  [[[
                    return (!!variables.ulm_custom_card_washer_machine_state
                      && !!states[variables.ulm_custom_card_washer_machine_state]?.state
                      && states[variables.ulm_custom_card_washer_machine_state].state === variables.ulm_custom_card_washer_machine_stop_state)
                        ? "toggle"
                        : "none";
                  ]]]
              state:
                - operator: "template"
                  value: >
                    [[[
                      return (!!variables.ulm_custom_card_washer_machine_state
                        && !!states[variables.ulm_custom_card_washer_machine_state]?.state
                        && states[variables.ulm_custom_card_washer_machine_state].state !== variables.ulm_custom_card_washer_machine_stop_state);
                    ]]]
                  styles:
                    icon:
                      - color: "rgba(var(--color-theme),0.2)"
              entity: "[[[ return variables.ulm_custom_card_washer_delayed_start; ]]]"
    row4:
      card:
        type: "custom:button-card"
        template: "list_3_items"
        styles:
          card:
            - padding: "0px"
            - margin-top: "12px"
        custom_fields:
          item1:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              tap_action:
                action: "call-service"
                service: "input_datetime.set_datetime"
                service_data:
                  entity_id: "[[[ return variables.ulm_custom_card_washer_delayed_starttime; ]]]"
                  time: >
                    [[[
                      if (!!variables.ulm_custom_card_washer_delayed_starttime
                        && !!states[variables.ulm_custom_card_washer_delayed_starttime]?.attributes) {
                        var timestamp = states[variables.ulm_custom_card_washer_delayed_starttime].attributes.timestamp

                        let unix_timestamp = timestamp - 4500;
                        // Create a new JavaScript Date object based on the timestamp
                        // multiplied by 1000 so that the argument is in milliseconds, not seconds.
                        var date = new Date(unix_timestamp * 1000);
                        // Hours part from the timestamp
                        var hours = date.getHours();
                        // Minutes part from the timestamp
                        var minutes = "0" + date.getMinutes();
                        // Seconds part from the timestamp
                        var seconds = "0" + date.getSeconds();
                        // Will display time in 10:30:23 format
                        return hours + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
                      } else {
                        return "00:00:00";
                      }
                    ]]]
              icon: "mdi:arrow-down"
          item2:
            card:
              type: "custom:button-card"
              template: "custom_card_haven_washer_delayed_text"
              tap_action:
                action: "call-service"
                service: "input_datetime.set_datetime"
                service_data:
                  entity_id: "[[[ return variables.ulm_custom_card_washer_delayed_starttime; ]]]"
                  time: >
                    [[[
                      if (!!variables.ulm_custom_card_washer_delayed_starttime
                        && !!states[variables.ulm_custom_card_washer_delayed_starttime]?.attributes) {
                        var timestamp = states[variables.ulm_custom_card_washer_delayed_starttime].attributes.timestamp

                        let unix_timestamp = timestamp - 3540;
                        // Create a new JavaScript Date object based on the timestamp
                        // multiplied by 1000 so that the argument is in milliseconds, not seconds.
                        var date = new Date(unix_timestamp * 1000);
                        // Hours part from the timestamp
                        var hours = date.getHours();
                        // Minutes part from the timestamp
                        var minutes = "0" + date.getMinutes();
                        // Seconds part from the timestamp
                        var seconds = "0" + date.getSeconds();
                        // Will display time in 10:30:23 format
                        return  hours + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
                      } else {
                        return "00:00:00";
                      }
                    ]]]
              hold_action:
                action: "call-service"
                service: "input_datetime.set_datetime"
                service_data:
                  entity_id: "[[[ variables.ulm_custom_card_washer_delayed_starttime ]]]"
                  time: >
                    [[[
                      if (!!variables.ulm_custom_card_washer_delayed_starttime
                        && !!states[variables.ulm_custom_card_washer_delayed_starttime]?.attributes) {
                        var timestamp = states[variables.ulm_custom_card_washer_delayed_starttime].attributes.timestamp

                        let unix_timestamp = timestamp - 3660;
                        // Create a new JavaScript Date object based on the timestamp
                        // multiplied by 1000 so that the argument is in milliseconds, not seconds.
                        var date = new Date(unix_timestamp * 1000);
                        // Hours part from the timestamp
                        var hours = date.getHours();
                        // Minutes part from the timestamp
                        var minutes = "0" + date.getMinutes();
                        // Seconds part from the timestamp
                        var seconds = "0" + date.getSeconds();
                        // Will display time in 10:30:23 format
                        return hours + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
                      } else {
                        return "00:00:00";
                      }
                    ]]]
              entity: "[[[ return variables.ulm_custom_card_washer_delayed_starttime; ]]]"
          item3:
            card:
              type: "custom:button-card"
              template: "widget_icon"
              tap_action:
                action: "call-service"
                service: "input_datetime.set_datetime"
                service_data:
                  entity_id: "[[[ return variables.ulm_custom_card_washer_delayed_starttime ]]]"
                  time: >
                    [[[
                      if (!!variables.ulm_custom_card_washer_delayed_starttime
                        && !!states[variables.ulm_custom_card_washer_delayed_starttime]?.attributes) {
                        var timestamp = states[variables.ulm_custom_card_washer_delayed_starttime].attributes.timestamp
                        let unix_timestamp = timestamp - 2700;
                        // Create a new JavaScript Date object based on the timestamp
                        // multiplied by 1000 so that the argument is in milliseconds, not seconds.
                        var date = new Date(unix_timestamp * 1000);
                        // Hours part from the timestamp
                        var hours = date.getHours();
                        // Minutes part from the timestamp
                        var minutes = "0" + date.getMinutes();
                        // Seconds part from the timestamp
                        var seconds = "0" + date.getSeconds();
                        // Will display time in 10:30:23 format
                        return hours + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
                      } else {
                        return "00:00:00";
                      }
                    ]]]
              icon: "mdi:arrow-up"

custom_card_haven_washer_state:
  show_icon: true
  show_name: false
  tap_action:
    action: "none"
  size: "20px"
  styles:
    card:
      - box-shadow: "none"
      - padding: "0px"
      - border-radius: "50%"
      - place-self: "center"
      - height: "42px"
      - width: "42px"
      - pointer-events: "auto"
      - background-color: "transparent"
    grid:
      - grid-template-areas: "'i'"
    icon:
      - color: "var(--google-grey)"

custom_card_haven_washer_delayed_text:
  template:
    - "ulm_translation_engine"
  tap_action:
    action: "toggle"
  show_icon: false
  show_label: true
  show_name: false
  label: "[[[ return variables.ulm_translation_state ]]]"
  styles:
    state:
      - color: "rgba(var(--color-theme),0.9)"
    grid:
      - grid-template-areas: "'l'"
    card:
      - box-shadow: "none"
      - padding: "0px"
      - background-color: "rgba(var(--color-theme),0.05)"
      - border-radius: "14px"
      - place-self: "center"
      - height: "42px"
  size: "20px"
  color: "var(--google-grey)"