((LitElement) => {
console.info(
'%c XIAOMI-VACUUM-CARD %c 4.5.0 ',
'color: cyan; background: black; font-weight: bold;',
'color: darkblue; background: white; font-weight: bold;',
);
const state = {
status: {
key: 'status',
icon: 'mdi:robot-vacuum',
},
battery: {
key: 'battery_level',
unit: '%',
icon: 'mdi:battery-charging-80',
},
mode: {
key: 'fan_speed',
icon: 'mdi:fan',
},
};
const attributes = {
main_brush: {
key: 'main_brush_left',
label: 'Main Brush: ',
unit: ' h',
},
side_brush: {
key: 'side_brush_left',
label: 'Side Brush: ',
unit: ' h',
},
filter: {
key: 'filter_left',
label: 'Filter: ',
unit: ' h',
},
sensor: {
key: 'sensor_dirty_left',
label: 'Sensor: ',
unit: ' h',
},
};
const buttons = {
start: {
label: 'Start',
icon: 'mdi:play',
service: 'vacuum.start',
},
pause: {
label: 'Pause',
icon: 'mdi:pause',
service: 'vacuum.pause',
},
stop: {
label: 'Stop',
icon: 'mdi:stop',
service: 'vacuum.stop',
},
spot: {
show: false,
label: 'Clean Spot',
icon: 'mdi:broom',
service: 'vacuum.clean_spot',
},
locate: {
label: 'Locate',
icon: 'mdi:map-marker',
service: 'vacuum.locate',
},
return: {
label: 'Return to Base',
icon: 'mdi:home-map-marker',
service: 'vacuum.return_to_base',
},
};
const compute = {
trueFalse: v => (v === true ? 'Yes' : (v === false ? 'No' : '-')),
divide100: v => Math.round(Number(v) / 100),
secToHour: v => Math.floor(Number(v) / 60 / 60),
}
const vendors = {
xiaomi: {
attributes: {
main_brush: {compute: compute.secToHour},
side_brush: {compute: compute.secToHour},
filter: {compute: compute.secToHour},
sensor: {compute: compute.secToHour},
}
},
xiaomi_mi: {
attributes: {
main_brush: {key: 'main_brush_hours'},
side_brush: {key: 'side_brush_hours'},
filter: {key: 'hypa_hours'},
sensor: {
key: 'mop_hours',
label: 'Mop: ',
},
},
},
valetudo: {
state: {
status: {key: 'state'},
},
attributes: {
main_brush: {key: 'mainBrush'},
side_brush: {key: 'sideBrush'},
filter: {key: 'filter'},
sensor: {key: 'sensor'},
},
},
roomba: {
attributes: {
main_brush: false,
side_brush: false,
filter: false,
sensor: false,
bin_present: {
key: 'bin_present',
label: 'Bin Present: ',
compute: compute.trueFalse,
},
bin_full: {
key: 'bin_full',
label: 'Bin Full: ',
compute: compute.trueFalse,
},
},
},
robovac: {
attributes: false,
buttons: {
stop: {show: false},
spot: {show: true},
},
},
ecovacs: {
attributes: false,
buttons: {
start: {service: 'vacuum.turn_on'},
pause: {service: 'vacuum.stop'},
stop: {service: 'vacuum.turn_off', show: false},
spot: {show: true},
},
},
deebot: {
buttons: {
start: {service: 'vacuum.turn_on'},
pause: {service: 'vacuum.stop'},
stop: {service: 'vacuum.turn_off'},
},
attributes: {
main_brush: {
key: 'component_main_brush',
compute: compute.divide100,
},
side_brush: {
key: 'component_side_brush',
compute: compute.divide100,
},
filter: {
key: 'component_filter',
compute: compute.divide100,
},
sensor: false,
},
},
deebot_slim: {
buttons: {
start: {service: 'vacuum.turn_on'},
pause: {service: 'vacuum.stop'},
stop: {service: 'vacuum.turn_off'},
},
attributes: {
main_brush: false,
side_brush: {key: 'component_side_brush'},
filter: {key: 'component_filter'},
sensor: false,
},
},
neato: {
state: {
mode: false,
},
attributes: {
main_brush: false,
side_brush: false,
filter: false,
sensor: false,
clean_area: {
key: 'clean_area',
label: 'Cleaned area: ',
unit: ' m2',
},
},
},
};
const html = LitElement.prototype.html;
const css = LitElement.prototype.css;
class XiaomiVacuumCard extends LitElement {
static get properties() {
return {
_hass: {},
config: {},
stateObj: {},
}
}
static get styles() {
return css`
.background {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
.title {
font-size: 20px;
padding: 12px 16px 8px;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.flex {
display: flex;
align-items: center;
justify-content: space-evenly;
}
.grid {
display: grid;
grid-template-columns: repeat(2, auto);
cursor: pointer;
}
.grid-content {
display: grid;
align-content: space-between;
grid-row-gap: 6px;
}
.grid-left {
text-align: left;
font-size: 110%;
padding-left: 10px;
border-left: 2px solid var(--primary-color);
}
.grid-right {
text-align: right;
padding-right: 10px;
border-right: 2px solid var(--primary-color);
}`;
}
render() {
return this.stateObj ? html`