@@ -262,8 +262,9 @@
}
.wheel {
+ margin-top: 1.5rem;
display: flex;
- flex-direction: column;
align-items: center;
+ justify-content: space-evenly;
}
diff --git a/src/lib/Main/Button.svelte b/src/lib/Main/Button.svelte
index f24ecaad..4391194c 100644
--- a/src/lib/Main/Button.svelte
+++ b/src/lib/Main/Button.svelte
@@ -246,9 +246,7 @@
break;
case 'alarm_control_panel':
- openModal(() => import('$lib/Modal/AlarmControlPanelModal.svelte'), {
- sel
- });
+ openModal(() => import('$lib/Modal/AlarmControlPanelModal.svelte'), { sel });
break;
case 'lock':
@@ -256,15 +254,11 @@
break;
case 'climate':
- openModal(() => import('$lib/Modal/ClimateModal.svelte'), {
- selected: sel
- });
+ openModal(() => import('$lib/Modal/ClimateModal.svelte'), { sel });
break;
case 'camera':
- openModal(() => import('$lib/Modal/CameraModal.svelte'), {
- sel
- });
+ openModal(() => import('$lib/Modal/CameraModal.svelte'), { sel });
break;
case 'media_player':
diff --git a/src/lib/Modal/ButtonConfig.svelte b/src/lib/Modal/ButtonConfig.svelte
index 2cf76401..ba9aeb5a 100644
--- a/src/lib/Modal/ButtonConfig.svelte
+++ b/src/lib/Modal/ButtonConfig.svelte
@@ -37,12 +37,10 @@
.sort()
.map((key) => ({ id: key, label: key }));
- $: options_attr = Object.keys(entity.attributes)
- .filter((key) => key !== 'friendly_name')
- .map((key) => ({
- id: key,
- label: key
- }));
+ $: options_attr = Object.keys(entity.attributes).map((key) => ({
+ id: key,
+ label: key
+ }));
function set(key: string, event?: any) {
sel = updateObj(sel, key, event);
@@ -238,7 +236,6 @@
options={options_attr}
placeholder={$lang('state')}
value={sel?.attribute}
- clearable={true}
on:change={(event) => {
set('attribute', event);
}}
diff --git a/src/lib/Modal/ClimateModal.svelte b/src/lib/Modal/ClimateModal.svelte
index 66d7d084..b76d91e1 100644
--- a/src/lib/Modal/ClimateModal.svelte
+++ b/src/lib/Modal/ClimateModal.svelte
@@ -4,98 +4,260 @@
import WheelPicker from '$lib/Components/WheelPicker.svelte';
import Icon from '@iconify/svelte';
import ConfigButtons from '$lib/Modal/ConfigButtons.svelte';
- import { getName } from '$lib/Utils';
+ import { getName, getSupport } from '$lib/Utils';
import { callService } from 'home-assistant-js-websocket';
+ import Select from '$lib/Components/Select.svelte';
export let isOpen: boolean;
- export let selected: any;
+ export let sel: any;
- $: entity = $states[selected?.entity_id];
+ $: entity = $states[sel?.entity_id];
$: entity_id = entity?.entity_id;
$: attributes = entity?.attributes;
+ // buttons or select, based on how many items
+ const MAX_ITEMS = 4;
+
+ /**
+ * Construct support based on Feature
+ * https://github.com/home-assistant/frontend/blob/dev/src/data/climate.ts
+ */
+
+ let supports: { [key: string]: boolean } = {};
+
+ enum Feature {
+ TARGET_TEMPERATURE = 1,
+ TARGET_TEMPERATURE_RANGE = 2,
+ TARGET_HUMIDITY = 4,
+ FAN_MODE = 8,
+ PRESET_MODE = 16,
+ SWING_MODE = 32,
+ AUX_HEAT = 64
+ }
+
+ $: if (sel?.entity_id) constructSupports();
+
+ function constructSupports() {
+ if (!attributes) return;
+
+ Object.keys(Feature)
+ .filter((key) => isNaN(Number(key)))
+ .forEach((key) => {
+ supports[key] = getSupport(attributes, Feature[key as keyof typeof Feature]);
+ });
+ }
+
+ /**
+ * Handles click
+ */
function handleClick(service: string, to_state: string) {
callService($connection, 'climate', 'set_' + service, {
entity_id,
[service]: to_state
});
+ // console.debug('climate.set_' + service, '->', to_state);
+ }
- console.debug('climate.set_' + service, '->', to_state);
+ /**
+ * Handles change
+ */
+ function handleChange() {
+ callService($connection, 'climate', 'set_temperature', {
+ entity_id,
+ target_temp_low: attributes?.target_temp_low,
+ target_temp_high: attributes?.target_temp_high
+ });
}
+ /**
+ * Options
+ */
const hvacModesIcons: Record
= {
- auto: 'mdi:thermostat-auto',
- heat: 'mdi:fire',
- heat_cool: 'mdi:sun-snowflake-variant',
cool: 'mdi:snowflake',
dry: 'mdi:water-percent',
+ fan_only: 'mdi:fan',
+ auto: 'mdi:thermostat-auto',
+ heat: 'mdi:fire',
off: 'mdi:power',
- fan_only: 'mdi:fan'
+ heat_cool: 'mdi:sun-snowflake-variant'
+ };
+
+ $: optionsHvacModes = attributes?.hvac_modes?.map((option: string) => ({
+ id: option,
+ label: $lang(option),
+ icon: hvacModesIcons?.[option] || 'mdi:fan'
+ }));
+
+ const fanModeIcons: Record = {
+ on: 'mdi:fan',
+ off: 'mdi:fan-off',
+ auto: 'mdi:fan-auto',
+ low: 'mdi:speedometer-slow',
+ medium: 'mdi:speedometer-medium',
+ high: 'mdi:speedometer',
+ middle: 'mdi:speedometer-medium',
+ focus: 'mdi:target',
+ diffuse: 'mdi:weather-windy'
+ };
+
+ $: optionsFanModes = attributes?.fan_modes?.map((option: string) => ({
+ id: option,
+ label: $lang(option),
+ icon: fanModeIcons?.[option] || 'mdi:fan'
+ }));
+
+ const swingModeIcons: Record = {
+ on: 'mdi:arrow-oscillating',
+ off: 'mdi:arrow-oscillating-off',
+ vertical: 'mdi:arrow-up-down',
+ horizontal: 'mdi:arrow-left-right',
+ both: 'mdi:arrow-all'
};
+
+ $: optionsSwingModes = attributes?.swing_modes?.map((option: string) => ({
+ id: option,
+ label: $lang(option),
+ icon: swingModeIcons?.[option] || 'mdi:fan'
+ }));
{#if isOpen}
- {getName(selected, entity)}
+ {getName(sel, entity)}
{#if attributes?.hvac_modes}
{$lang('hvac_modes')}
-
+ {#if attributes?.hvac_modes?.length <= MAX_ITEMS}
+
+ {:else if optionsHvacModes}
+