201 lines
5.7 KiB
TypeScript
201 lines
5.7 KiB
TypeScript
import { HassEntity } from 'home-assistant-js-websocket';
|
|
import { UpdateEntity, updateIsInstalling } from '../ha/update.js';
|
|
import { alarmPanelIcon } from './alarm-panel-icon';
|
|
import { binarySensorIcon } from './binary-sensor-icon';
|
|
import { coverIcon } from './cover-icon';
|
|
import { sensorIcon } from './sensor-icon';
|
|
|
|
export const DEFAULT_DOMAIN_ICON = 'mdi:bookmark';
|
|
|
|
const FIXED_DOMAIN_ICONS = {
|
|
alert: 'mdi:alert',
|
|
air_quality: 'mdi:air-filter',
|
|
automation: 'mdi:robot',
|
|
calendar: 'mdi:calendar',
|
|
camera: 'mdi:video',
|
|
climate: 'mdi:thermostat',
|
|
configurator: 'mdi:cog',
|
|
conversation: 'mdi:text-to-speech',
|
|
counter: 'mdi:counter',
|
|
fan: 'mdi:fan',
|
|
google_assistant: 'mdi:google-assistant',
|
|
group: 'mdi:google-circles-communities',
|
|
homeassistant: 'mdi:home-assistant',
|
|
homekit: 'mdi:home-automation',
|
|
image_processing: 'mdi:image-filter-frames',
|
|
input_button: 'mdi:gesture-tap-button',
|
|
input_datetime: 'mdi:calendar-clock',
|
|
input_number: 'mdi:ray-vertex',
|
|
input_select: 'mdi:format-list-bulleted',
|
|
input_text: 'mdi:form-textbox',
|
|
light: 'mdi:lightbulb',
|
|
mailbox: 'mdi:mailbox',
|
|
notify: 'mdi:comment-alert',
|
|
number: 'mdi:ray-vertex',
|
|
persistent_notification: 'mdi:bell',
|
|
person: 'mdi:account',
|
|
plant: 'mdi:flower',
|
|
proximity: 'mdi:apple-safari',
|
|
remote: 'mdi:remote',
|
|
scene: 'mdi:palette',
|
|
script: 'mdi:script-text',
|
|
select: 'mdi:format-list-bulleted',
|
|
sensor: 'mdi:eye',
|
|
siren: 'mdi:bullhorn',
|
|
simple_alarm: 'mdi:bell',
|
|
sun: 'mdi:white-balance-sunny',
|
|
timer: 'mdi:timer-outline',
|
|
updater: 'mdi:cloud-upload',
|
|
vacuum: 'mdi:robot-vacuum',
|
|
water_heater: 'mdi:thermometer',
|
|
weather: 'mdi:weather-cloudy',
|
|
zone: 'mdi:map-marker-radius',
|
|
};
|
|
|
|
export function domainIcon(domain: string, entity?: HassEntity, state?: string): string {
|
|
switch (domain) {
|
|
case 'alarm_control_panel':
|
|
return alarmPanelIcon(state);
|
|
|
|
case 'binary_sensor':
|
|
return binarySensorIcon(state, entity);
|
|
|
|
case 'button':
|
|
switch (entity?.attributes.device_class) {
|
|
case 'restart':
|
|
return 'mdi:restart';
|
|
case 'update':
|
|
return 'mdi:package-up';
|
|
default:
|
|
return 'mdi:gesture-tap-button';
|
|
}
|
|
|
|
case 'cover':
|
|
return coverIcon(state, entity);
|
|
|
|
case 'device_tracker':
|
|
if (entity?.attributes.source_type === 'router') {
|
|
return state === 'home' ? 'mdi:lan-connect' : 'mdi:lan-disconnect';
|
|
}
|
|
if (['bluetooth', 'bluetooth_le'].includes(entity?.attributes.source_type)) {
|
|
return state === 'home' ? 'mdi:bluetooth-connect' : 'mdi:bluetooth';
|
|
}
|
|
return state === 'not_home' ? 'mdi:account-arrow-right' : 'mdi:account';
|
|
|
|
case 'humidifier':
|
|
return state && state === 'off' ? 'mdi:air-humidifier-off' : 'mdi:air-humidifier';
|
|
|
|
case 'input_boolean':
|
|
return state === 'on' ? 'mdi:check-circle-outline' : 'mdi:close-circle-outline';
|
|
|
|
case 'lock':
|
|
switch (state) {
|
|
case 'unlocked':
|
|
return 'mdi:lock-open';
|
|
case 'jammed':
|
|
return 'mdi:lock-alert';
|
|
case 'locking':
|
|
case 'unlocking':
|
|
return 'mdi:lock-clock';
|
|
default:
|
|
return 'mdi:lock';
|
|
}
|
|
|
|
// Taken from https://github.com/home-assistant/frontend/blob/45646eaf0bfc86aa0d0d6b73809ef0b32abb5729/src/common/entity/domain_icon.ts#L138-L172
|
|
case 'media_player':
|
|
switch (entity?.attributes.device_class) {
|
|
case 'speaker':
|
|
switch (state) {
|
|
case 'playing':
|
|
return 'mdi:speaker-play';
|
|
case 'paused':
|
|
return 'mdi:speaker-pause';
|
|
case 'off':
|
|
return 'mdi:speaker-off';
|
|
default:
|
|
return 'mdi:speaker';
|
|
}
|
|
case 'tv':
|
|
switch (state) {
|
|
case 'playing':
|
|
return 'mdi:television-play';
|
|
case 'paused':
|
|
return 'mdi:television-pause';
|
|
case 'off':
|
|
return 'mdi:television-off';
|
|
default:
|
|
return 'mdi:television';
|
|
}
|
|
default:
|
|
switch (state) {
|
|
case 'playing':
|
|
case 'paused':
|
|
return 'mdi:cast-connected';
|
|
case 'off':
|
|
return 'mdi:cast-off';
|
|
default:
|
|
return 'mdi:cast';
|
|
}
|
|
}
|
|
|
|
case 'switch':
|
|
switch (entity?.attributes.device_class) {
|
|
case 'outlet':
|
|
return state === 'on' ? 'mdi:power-plug' : 'mdi:power-plug-off';
|
|
case 'switch':
|
|
return state === 'on' ? 'mdi:toggle-switch' : 'mdi:toggle-switch-off';
|
|
default:
|
|
return 'mdi:flash';
|
|
}
|
|
|
|
case 'zwave':
|
|
switch (state) {
|
|
case 'dead':
|
|
return 'mdi:emoticon-dead';
|
|
case 'sleeping':
|
|
return 'mdi:sleep';
|
|
case 'initializing':
|
|
return 'mdi:timer-sand';
|
|
default:
|
|
return 'mdi:z-wave';
|
|
}
|
|
|
|
case 'sensor': {
|
|
const icon = sensorIcon(entity);
|
|
if (icon) {
|
|
return icon;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 'input_datetime':
|
|
if (!entity?.attributes.has_date) {
|
|
return 'mdi:clock';
|
|
}
|
|
if (!entity.attributes.has_time) {
|
|
return 'mdi:calendar';
|
|
}
|
|
break;
|
|
|
|
case 'sun':
|
|
return entity?.state === 'above_horizon'
|
|
? FIXED_DOMAIN_ICONS[domain]
|
|
: 'mdi:weather-night';
|
|
|
|
case 'update':
|
|
return entity?.state === 'on'
|
|
? updateIsInstalling(entity as UpdateEntity)
|
|
? 'mdi:package-down'
|
|
: 'mdi:package-up'
|
|
: 'mdi:package';
|
|
}
|
|
|
|
if (domain in FIXED_DOMAIN_ICONS) {
|
|
return FIXED_DOMAIN_ICONS[domain];
|
|
}
|
|
|
|
console.warn(`Unable to find icon for domain: ${domain}`);
|
|
return DEFAULT_DOMAIN_ICON;
|
|
}
|