Add Washing Machine Card
Michelone86 opened this issue Β· comments
Hi super @neilimixamo, I would like to use the EQUIPMENT tab to view the controls for my Washing Machine and Dryer (both Electrolux). Any ideas about it?
ps. I don't have other devices to insert in the EQUIPMENT tab, I just need to be able to control them. Thank you!
Hi @Michelone86, since I don't have connected washing and dryer machines myself, could you tell me more about the brands/products you use?
Could you also detail the functions you would like to integrate into the cards (e.g., start a wash, stop it, check the status or its power consumption, etc.) as well as the style you prefer?
If you only want to display two cards in your equipment view, we could quadruple the card size, which would allow for more controls or information to be displayed.
There is also a nice existing 'Custom-card Washer' proposed by UI-Minimalist, what do you think about it ? We could draw inspiration from it and create a QLM card that integrates seamlessly with the rest of its theme.
Feel free to provide sketches or drawings of what you envision for greater clarity."
Hello @neilimixamo, the card you proposed is really very interesting and would be great for me!
The controls I would like to see are quite simple: Current State (on/off), Wash Phase, Pause, Resume, Remaining Time. I currently use this Electrolux integration https://github.com/albaintor/homeassistant_electrolux_status.
Thank you so much for the time you dedicate to this great work, you are really good ππ
Hi @neilimixamo, unfortunately I don't have that much programming skills and I can't figure out how to make this card work with my Electrolux appliances and your qlm. Could you help me? π
If you only need to see the washing phase, remaining time, and control start/pause actions for the machine, we can maintain a minimalist approach by using the basic QLM card model as shown in this example.
The progress state will be represented by the appropriate icon for each cycle phase and a slider, while the remaining time will be displayed as a label when the machine is running and will show "paused" when the machine is paused. Does this card meet your requirements?
Since I don't have access to such a device, I need the following information:
- Entity name of your washing machine
- Screenshot of the "dev tool" window for this entity showing its attributes
- Entity name for starting/pausing your washing machine
- Entity name indicating the washing cycle
- Entity name indicating the remaining time
Hi @neilimixamo , I'm so happy to hear that you can view and control my washing machine directly with your QLM! The example you showed me is really what I need!
Here is the data you requested:
Entity name: electrolux_lavatrice
Entity name for starting: button.electrolux_lavatrice_executecommand_start
Entity name for pausing: button.electrolux_lavatrice_executecommand_pause
Entity name for resume: button.electrolux_lavatrice_executecommand_resume
Entity name for washing cycle: sensor.electrolux_lavatrice_cyclephase and sensor.electrolux_lavatrice_cyclesubphase
Entity name for remaining time: sensor.electrolux_lavatrice_timetoend
I also attach all the screenshots from the developers section.
ps. I will also need to insert my dryer (electrolux), but I think I will be able to adapt your work without giving you further trouble ;)
Ok, add first this new "appliance.yaml" beta template,
appliance (beta).yaml
appliance:
template:
- basic_card
- badge_battery
variables:
entity:
states: ["starting", "washing", "rinsing", "drying"] # add/adapt terms if needed
label_on: 'Active'
label_off: 'Inactive'
styles:
card:
- background-color: |
[[[
if (variables.entity) {
const state = states[variables.entity].state;
if (state !== 'off' && state !== 'paused') {
return 'var(--fan-background-active)';
} else {
return 'var(--fan-background-inactive)';
}
} else {
return 'var(--fan-background-inactive)';
}
]]]
custom_fields:
slider_visible:
card:
type: custom:my-slider-v2
entity: |
[[[
if (variables.entity) {
return variables.entity;
} else {
return '';
}
]]]
intermediate: true
styles:
card:
- display: block
- position: absolute
- height: 100%
- width: 100%
- background-color: transparent
- border-radius: 27px
- box-shadow: none
- bottom: 0vh
- left: 0vw
container:
- width: 100%
- height: 100%
- position: absolute
- bottom: 0vh
- right: 0vw
- overflow: hidden
- border-radius: 27px
track:
- width: 100%
- height: 100%
- position: absolute
- bottom: 0vh
- right: 0vw
- border-radius: 27px
- background-color: |
[[[
if (variables.entity) {
var state = states[variables.entity].state.toLowerCase();
var percentage = states[variables.entity].attributes.percentage;
if (state === 'on') {
return 'var(--fan-slider-track-active)';
}
}
return 'var(--fan-slider-track-inactive)';
]]]
progress:
- height: 100%
- background: |
[[[
if (variables.entity) {
var state = states[variables.entity].state.toLowerCase();
var percentage = states[variables.entity].attributes.percentage;
if (variables.states.some(s => state.includes(s.toLowerCase()))) {
return 'var(--fan-background-active)';
}
}
return 'var(--fan-background-inactive)';
]]]
- border-radius: 27px 0px 0px 27px
thumb:
- width: 0px
icon:
card:
icon: |
[[[
if (variables.entity) {
const state = states[variables.entity].state.toLowerCase();
if (state.includes('starting')) {
return 'mdi:power';
} else if (state.includes('washing')) {
return 'mdi:water';
} else if (state.includes('rinsing')) {
return 'mdi:water-pump';
} else if (state.includes('drying')) {
return 'mdi:weather-sunny';
} else if (state.includes('paused')) {
return 'mdi:pause';
} else {
return 'mdi:washing-machine';
}
} else {
return 'mdi:help';
}
]]]
styles:
card:
- overflow: visible
- background-color: |
[[[
if (variables.entity) {
const state = states[variables.entity].state;
if (state !== 'off' && state !== 'paused') {
return 'var(--fan-icon-background-active)';
} else {
return 'var(--fan-icon-background-inactive)';
}
} else {
return 'var(--fan-icon-background-inactive)';
}
]]]
icon:
- color: 'var(--fan-icon-active)'
tap_action:
action: toggle
hold_action:
action: none
custom_fields:
badge:
type: custom:button-card # calls for the 'badge_battery' template
name:
card:
label: |
[[[
if (variables.entity) {
if (states[variables.entity].state === "unavailable") {
return 'Unavailable';
}else if (states[variables.entity].state === "paused") {
return 'In Pausa';
} else {
var state = states[variables.entity].state;
if (state != 'off') {
return states[variables.label_on].state;
} else {
return variables.label_off;
}
}
} else if (variables.label) {
return variables.label;
} else {
return 'Label';
}
]]]
then create the following card and give me feedback.
- type: custom:button-card
template: appliance
variables:
entity: sensor.electrolux_lavatrice_appliancestate
name: Lavatrice
label_on: sensor.electrolux_lavatrice_timetoend
label_off: 'Disattivata'
icon_tap_action:
action: call-service
service: button.press
service_data:
entity_id: >
[[[
if (states[variables.entity].state.toLowerCase() === 'off') {
return 'button.electrolux_lavatrice_executecommand_start';
} else if (states[variables.entity].state.toLowerCase() === 'paused') {
return 'button.electrolux_lavatrice_executecommand_resume';
} else {
return 'button.electrolux_lavatrice_executecommand_pause';
}
]]]
Can you also list the possible states of the entities sensor.electrolux_lavatrice_appliancestate
, sensor.electrolux_lavatrice_cyclephase
and sensor.electrolux_lavatrice_cyclesubphasecycle
?
Which entity will indicate "washing", "rinsing", "drying", "paused" ?
Hi @neilimixamo, I created the board!
The minutes remaining for the end of the cycle are correct. If I click on the label, the sensor.electrolux_lavatrice_appliancestate entity screen opens. If I click on the icon instead, I get the error "Service sensor.turn_off not found".
123054_VRecorder.mp4
These are the states I was able to read since the last wash:
sensor.electrolux_lavatrice_appliancestate : off, running, end of cycle.
sensor.electrolux_lavatrice_cyclephase : unavailable, wash, rinse, spin.
sensor.electrolux_lavatrice_cyclesubphasecycle : not available, add garment, wash, rinse.
I await your instructions, thank you!
This new code should fix the action bug and should adapt the icon and label according to the progress state of the washing machine, while displaying the remaining time in minutes.
Can you make sure that the entity 'sensor.electrolux_lavatrice_appliancestate' also indicates a 'paused' state?
appliance (beta 2).yaml
appliance:
template:
- basic_card
- badge_battery
variables:
entity:
label_on: 'Attivata'
label_off: 'Disattivata'
styles:
card:
- background-color: |
[[[
if (variables.entity) {
const state = states[variables.entity].state;
if (state !== 'off' && state !== 'paused') {
return 'var(--fan-background-active)';
} else {
return 'var(--fan-background-inactive)';
}
} else {
return 'var(--fan-background-inactive)';
}
]]]
custom_fields:
icon:
card:
icon: |
[[[
const state = states[variables.entity].state.toLowerCase();
const phase = states['sensor.electrolux_lavatrice_cyclephase'].state.toLowerCase();
if (state === 'off') {
return 'mdi:washing-machine-off';
} else if (state === 'running') {
if (phase === 'wash') {
return 'mdi:water';
} else if (phase === 'rinse') {
return 'mdi:water-pump';
} else if (phase === 'spin') {
return 'mdi:turbine';
} else {
return 'mdi:washing-machine';
}
} else if (state === 'end of cycle') {
return 'mdi:check';
} else if (state === 'paused') {
return 'mdi:pause';
} else {
return 'mdi:help';
}
]]]
styles:
card:
- overflow: visible
- background-color: |
[[[
if (variables.entity) {
const state = states[variables.entity].state;
if (state !== 'off' && state !== 'paused') {
return 'var(--fan-icon-background-active)';
} else {
return 'var(--fan-icon-background-inactive)';
}
} else {
return 'var(--fan-icon-background-inactive)';
}
]]]
icon:
- color: 'var(--fan-icon-active)'
custom_fields:
badge:
type: custom:button-card
name:
card:
label: |
[[[
const state = states[variables.entity].state.toLowerCase();
const phase = states['sensor.electrolux_lavatrice_cyclephase'].state.toLowerCase();
const timetoend = states['sensor.electrolux_lavatrice_timetoend'].state;
if (state === 'off') {
return variables.label_off;
} else if (state === 'running') {
if (phase === 'wash') {
return 'Lavaggio - ' + timetoend + 'min';
} else if (phase === 'rinse') {
return 'Risciacquo - ' + timetoend + 'min';
} else if (phase === 'spin') {
return 'Asciugatura - ' + timetoend + 'min';
} else {
return variables.label_on + ' - ' + timetoend + 'min';
}
} else if (state === 'end of cycle') {
return 'Finito';
} else {
return 'Label';
}
]]]
- type: custom:button-card
template: appliance
variables:
entity: sensor.electrolux_lavatrice_appliancestate
name: Lavatrice
icon_tap_action:
action: call-service
service: button.press
service_data:
entity_id: >
[[[
const state = states[variables.entity].state.toLowerCase();
const button = 'button.electrolux_lavatrice_executecommand_';
if (state === 'off') {
return button + 'start';
} else if (state === 'paused') {
return button + 'resume';
} else {
return button + 'pause';
}
]]]
This template is currently not applicable to other devices but I'll try to make it more generic once we have finalized this card and as mentioned earlier, I cannot test this code myself, so I have to rely on your observations for the following improvements ;)
Hi @neilimixamo , the code works perfectly!
Is it possible to move the remaining minutes under the wash cycle name? Thank you!
Ok the last solution seems the best to me, it would be perfect! (Replace state by name)
Ok, let's try this then :
appliance (beta 3).yaml
appliance:
template:
- basic_card
- badge_battery
variables:
entity:
label_on: 'Attivata'
label_off: 'Disattivata'
styles:
card:
- background-color: |
[[[
if (variables.entity) {
const state = states[variables.entity].state;
if (state !== 'off' && state !== 'paused') {
return 'var(--fan-background-active)';
} else {
return 'var(--fan-background-inactive)';
}
} else {
return 'var(--fan-background-inactive)';
}
]]]
custom_fields:
icon:
card:
icon: |
[[[
const state = states[variables.entity].state.toLowerCase();
const phase = states['sensor.electrolux_lavatrice_cyclephase'].state.toLowerCase();
if (state === 'off') {
return 'mdi:washing-machine-off';
} else if (state === 'running') {
if (phase === 'wash') {
return 'mdi:hand-water';
} else if (phase === 'rinse') {
return 'mdi:water';
} else if (phase === 'spin') {
return 'mdi:turbine';
} else {
return 'mdi:washing-machine';
}
} else if (state === 'end of cycle') {
return 'mdi:check';
} else if (state === 'paused') {
return 'mdi:pause';
} else {
return 'mdi:help';
}
]]]
styles:
card:
- overflow: visible
- background-color: |
[[[
if (variables.entity) {
const state = states[variables.entity].state;
if (state !== 'off' && state !== 'paused') {
return 'var(--fan-icon-background-active)';
} else {
return 'var(--fan-icon-background-inactive)';
}
} else {
return 'var(--fan-icon-background-inactive)';
}
]]]
icon:
- color: 'var(--fan-icon-active)'
custom_fields:
badge:
type: custom:button-card
name:
card:
name: |
[[[
const state = states[variables.entity].state.toLowerCase();
const phase = states['sensor.electrolux_lavatrice_cyclephase'].state.toLowerCase();
if (state === 'off') {
return variables.name;
} else if (state === 'paused') {
return 'In Pausa';
} else if (state === 'running') {
if (phase === 'wash') {
return 'Lavaggio' ;
} else if (phase === 'rinse') {
return 'Risciacquo';
} else if (phase === 'spin') {
return 'Asciugatura';
} else {
return variables.name;
}
} else if (state === 'end of cycle') {
return 'Finito';
} else {
return 'Name';
}
]]]
label: |
[[[
const state = states[variables.entity].state.toLowerCase();
const timetoend = states['sensor.electrolux_lavatrice_timetoend'].state;
if (state === 'off') {
return variables.label_off;
} else if (state === 'running') {
return timetoend + ' min';
} else if (state === 'end of cycle') {
return 'Finito';
} else {
return variables.label_on ;
}
]]]
Ok, I did a quick test and it seems to work well! In the next few days I'll do some complete tests and update you, I'll wait to close the topic.
Thanks Super @neilimixamo πππ
Hi @neilimixamo , I've been testing your card for a few days, everything works great and I even managed to get the dryer to work by adapting its entities based on your code!
Thank you so much, your QLM Dashboard is really perfect ππ
Hi @Michelone86, I'm glad to hear that you achieved the dashboard you wanted. However, I notice that the cards are blue even though their status is "Spenta", they should be greyded instead, no?
Hi @neilimixamo , yes the cards are Blue even if they are turned off... π€
Is the state of your inactive washing machine "off" or "end of cycle" ? Cause every other states than "off" or "paused" will return a blue card
The state of the switched off washing machine is OFF.
Can you try to change 'OFF' to 'off' in the dev tools to see if it fixes the problem ?
If it does, replace lines 15 and 59 of the appliance template with
if (state.toLowerCase() !== 'off' && state.toLowerCase() !== 'paused') {
Hi @neilimixamo, I made the change you told me to do, now everything works correctly! Thank you βπ»