Skip to content

Commit

Permalink
feat: add a slider to adjust speed
Browse files Browse the repository at this point in the history
This commit introduces a slider to change purifier's speed

BREAKING CHANGE: The speed option is removed in favour of percentage
  • Loading branch information
denysdovhan committed Dec 1, 2021
1 parent 5d4f8c4 commit fff54f5
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 73 deletions.
104 changes: 36 additions & 68 deletions src/purifier-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ if (!customElements.get('ha-icon-button')) {
);
}

const SUPPORT_SET_SPEED = 1;
const SUPPORT_PRESET_MODE = 8;
class PurifierCard extends LitElement {
static get properties() {
Expand Down Expand Up @@ -59,14 +58,6 @@ class PurifierCard extends LitElement {
return this.hass.states[this.config.entity];
}

get showSpeed() {
if (this.config.show_speed === undefined) {
return false;
}

return this.config.show_speed;
}

get showPresetMode() {
if (this.config.show_preset_mode === undefined) {
return true;
Expand Down Expand Up @@ -152,16 +143,16 @@ class PurifierCard extends LitElement {
);
}

handleSpeed(e) {
const speed = e.target.getAttribute('value');
this.callService('fan.set_speed', { speed });
}

handlePresetMode(e) {
const preset_mode = e.target.getAttribute('value');
this.callService('fan.set_preset_mode', { preset_mode });
}

handlePercentage(e) {
const percentage = e.detail.value;
this.callService('fan.set_percentage', { percentage });
}

callService(service, options = {}, isRequest = true) {
const [domain, name] = service.split('.');
this.hass.callService(domain, name, {
Expand All @@ -175,53 +166,6 @@ class PurifierCard extends LitElement {
}
}

renderSpeed() {
const {
attributes: { speed, speed_list, supported_features },
} = this.entity;

// TODO handle percentages
if (
!this.showSpeed ||
!speed_list ||
!(supported_features & SUPPORT_SET_SPEED)
) {
return html``;
}

const selected = speed_list.indexOf(speed);

return html`
<div class="speed>
<paper-menu-button
slot="dropdown-trigger"
.horizontalAlign=${'right'}
.verticalAlign=${'top'}
.verticalOffset=${40}
.noAnimations=${true}
@click="${(e) => e.stopPropagation()}"
>
<paper-button slot="dropdown-trigger">
<ha-icon icon="mdi:fan"></ha-icon>
<span show=${true}> ${localize(`speed.${speed}`) || speed} </span>
</paper-button>
<paper-listbox
slot="dropdown-content"
selected=${selected}
@click="${(e) => this.handleSpeed(e)}"
>
${speed_list.map(
(item) =>
html`<paper-item value=${item}
>${localize(`speed.${item}`) || item}</paper-item
>`
)}
</paper-listbox>
</paper-menu-button>
</div>
`;
}

renderPresetMode() {
const {
attributes: { preset_mode, preset_modes, supported_features },
Expand Down Expand Up @@ -294,6 +238,36 @@ class PurifierCard extends LitElement {
`;
}

renderSlider() {
const {
state,
attributes: { percentage, percentage_step },
} = this.entity;

const disabled = state !== 'on';
const stateClass = !disabled ? 'working' : 'standby';

return html`
<div class="slider">
<round-slider
value=${percentage}
step=${percentage_step}
?disabled="${disabled}"
@value-changed=${(e) => this.handlePercentage(e)}
>
</round-slider>
<div class="slider-center image ${stateClass}">
<div class="slider-content">
${this.renderAQI()}
</div>
<div class="slider-value">
${percentage}%
</div>
</div>
</div>
`;
}

renderName() {
const {
attributes: { friendly_name },
Expand Down Expand Up @@ -426,11 +400,6 @@ class PurifierCard extends LitElement {
`;
}

const { state } = this.entity;

const stateClass = state === 'on' ? 'working' : 'standby';
const className = !this.compactView ? stateClass : 'compact';

return html`
<ha-card>
<div
Expand All @@ -439,11 +408,10 @@ class PurifierCard extends LitElement {
?more-info="true"
>
<div class="header">
<div class="speed">${this.renderSpeed()}</div>
<div class="preset-mode">${this.renderPresetMode()}</div>
</div>
<div class="image ${className}">${this.renderAQI()}</div>
<div class="controls">${this.renderSlider()}</div>
<div class="metadata">${this.renderName()} ${this.renderState()}</div>
Expand Down
51 changes: 46 additions & 5 deletions src/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,51 @@ export default css`
margin-top: 5px;
}
.image {
background: center / contain no-repeat;
height: 250px;
.controls {
display: flex;
justify-content: center;
align-items: center;
}
.slider {
height: 100%;
width: 100%;
position: relative;
max-width: 250px;
min-width: 100px;
}
.slider-center {
position: absolute;
width: calc(100% - 90px);
height: calc(100% - 10px);
box-sizing: border-box;
border-radius: 100%;
left: 45px;
top: 20px;
text-align: center;
overflow-wrap: break-word;
pointer-events: none;
}
.slider-content {
position: absolute;
transform: translate(-50%, -50%);
width: 100%;
top: 50%;
left: 50%;
}
.slider-value {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
transform: translateY(-50%);
font-size: 16px;
}
.image {
background: center / contain no-repeat;
}
.image.working {
Expand Down Expand Up @@ -135,9 +174,11 @@ export default css`
border-right: 1px solid rgba(255, 255, 255, 0.2);
flex-grow: 1;
}
.stats-block:last-child {
border: 0px;
}
.stats-value {
font-size: 20px;
font-weight: bold;
Expand Down Expand Up @@ -200,6 +241,6 @@ export default css`
.toolbar ha-icon {
color: var(--primary-color);
display:flex;
display: flex;
}
`;

0 comments on commit fff54f5

Please sign in to comment.