Skip to content

Commit

Permalink
Merge pull request #214 from matt8707/water-heater
Browse files Browse the repository at this point in the history
Add 'water_heater' modal support, closes #149
  • Loading branch information
matt8707 authored Jan 19, 2024
2 parents 1bc3dd4 + 726bee8 commit 6bb98a9
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 5 deletions.
8 changes: 4 additions & 4 deletions PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ List grouped by domains and categorized based on their similar behaviors
### Climate

- [x] climate
- [ ] horizontal temp select
- [ ] issue <https://github.com/matt8707/ha-fusion/issues/22>
- [x] horizontal temp select
- [x] issue <https://github.com/matt8707/ha-fusion/issues/22>
- [x] fan
- [ ] humidifier
- [ ] water_heater
- [x] humidifier
- [x] water_heater

### Other

Expand Down
4 changes: 4 additions & 0 deletions src/lib/Components/StateLogic.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
{:else if getDomain(entity_id) === 'humidifier' && entity?.state === 'on' && attributes?.action}
{$lang('humidifier_' + attributes?.action)}

<!-- Water Heater -->
{:else if getDomain(entity_id) === 'water_heater'}
{$lang('water_heater_' + entity?.state)}

<!-- Input Number / Number -->
{:else if entity_id && (getDomain(entity_id) === 'input_number' || getDomain(entity_id) === 'number')}
{Number(state) || $lang('unknown')}
Expand Down
4 changes: 4 additions & 0 deletions src/lib/Main/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@
openModal(() => import('$lib/Modal/CameraModal.svelte'), { sel });
break;
case 'water_heater':
openModal(() => import('$lib/Modal/WaterHeaterModal.svelte'), { sel });
break;
case 'humidifier':
openModal(() => import('$lib/Modal/HumidifierModal.svelte'), { sel });
break;
Expand Down
179 changes: 179 additions & 0 deletions src/lib/Modal/WaterHeaterModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<script lang="ts">
import { states, lang, connection, ripple } from '$lib/Stores';
import Modal from '$lib/Modal/Index.svelte';
import ConfigButtons from '$lib/Modal/ConfigButtons.svelte';
import { getName, getSupport } from '$lib/Utils';
import { callService } from 'home-assistant-js-websocket';
import RangeSlider from '$lib/Components/RangeSlider.svelte';
import Select from '$lib/Components/Select.svelte';
import Ripple from 'svelte-ripple';
import Toggle from '$lib/Components/Toggle.svelte';
export let isOpen: boolean;
export let sel: any;
$: entity = $states?.[sel?.entity_id];
$: attributes = entity?.attributes;
$: toggle = entity?.state !== 'off';
$: supported_features = attributes?.supported_features;
$: supports = getSupport(supported_features, {
TARGET_TEMPERATURE: 1,
OPERATION_MODE: 2,
AWAY_MODE: 4
});
$: options = attributes?.operation_list?.map((option: string) => ({
id: option,
icon: icons?.[option] || 'mdi:water-percent',
label: $lang(`water_heater_${option}`)
}));
const icons: Record<string, string> = {
eco: 'mdi:leaf',
electric: 'mdi:lightning-bolt',
performance: 'mdi:rocket-launch',
high_demand: 'mdi:finance',
heat_pump: 'mdi:heat-wave',
gas: 'mdi:fire-circle',
off: 'mdi:power'
};
/**
* Handle service calls
* 'toggle' | 'set_humidity' | 'set_mode'
*/
function handleEvent(
service: string,
payload: string | number | boolean | undefined = undefined
) {
if (!entity?.entity_id) return;
let data: Record<string, string | number | boolean | undefined> = {
entity_id: entity?.entity_id
};
if (service === 'set_temperature') {
data.temperature = payload;
} else if (service === 'set_operation_mode') {
data.operation_mode = payload;
} else if (service === 'set_away_mode') {
data.away_mode = payload;
}
callService($connection, 'water_heater', service, data);
}
</script>

{#if isOpen}
<Modal>
<h1 slot="title">{getName(sel, entity)}</h1>

<!-- TOGGLE -->
<h2>{$lang('toggle')}</h2>

<Toggle
bind:checked={toggle}
on:change={() => {
const service = entity?.state !== 'off' ? 'turn_off' : 'turn_on';
handleEvent(service);
}}
/>

<!-- STATE -->
{#if entity?.state}
<h2>{$lang('state')}</h2>

{$lang('water_heater_' + entity?.state)}
{/if}

<!-- TEMPERATURE -->
<h2>
{$lang('target')}

<span class="align-right">
{#if attributes?.current_temperature}
{attributes?.current_temperature}° ->
{/if}

{attributes?.temperature
</span>
</h2>

{#if attributes?.temperature}
<RangeSlider
bind:value={attributes.temperature}
min={parseInt(attributes?.min_temp)}
max={parseInt(attributes?.max_temp)}
on:change={(event) => {
handleEvent('set_temperature', event?.detail);
}}
/>
{/if}

<!-- OPERATION_MODE -->
{#if supports?.OPERATION_MODE && options}
<h2>
{$lang('mode')}
</h2>

<Select
{options}
keepFocus={true}
customItems={true}
placeholder={$lang('mode')}
value={attributes?.operation_mode}
on:change={(event) => {
handleEvent('set_operation_mode', event?.detail);
}}
/>
{/if}

<!-- AWAY_MODE -->
{#if supports?.AWAY_MODE}
<h2>
{$lang('water_heater_away_mode')}
</h2>

<div class="button-container">
<button
class:selected={attributes?.away_mode === 'off'}
on:click={() => {
handleEvent('set_away_mode', false);
}}
use:Ripple={$ripple}
>
{$lang('off')}
</button>

<button
class:selected={attributes?.away_mode === 'on'}
on:click={() => {
handleEvent('set_away_mode', true);
}}
use:Ripple={$ripple}
>
{$lang('on')}
</button>
</div>
{/if}

<!-- <h2>Supports</h2>
<code>
<pre>
{JSON.stringify(supports, null, 2)}
</pre>
</code>
<h2>Entity</h2>
<code>
<pre>
{JSON.stringify(entity, null, 2)}
</pre>
</code> -->

<ConfigButtons />
</Modal>
{/if}
10 changes: 9 additions & 1 deletion src/lib/Stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,16 @@ export const onStates = readable([
'playing',
'preheating',
'unlocked',
// vacuum
'cleaning',
'returning'
'returning',
// water_heater
'eco',
'electric',
'performance',
'high_demand',
'heat_pump',
'gas'
]);

// drawer
Expand Down

0 comments on commit 6bb98a9

Please sign in to comment.