Files
ha-frontend-cdce8p/src/util/hass-util.html
T
Matt Schmitt 13f5e33087 Add device class for low battery (#696)
* Add device class for low battery

* Fix per comments

* Update per comments

* Update per comments

Sorting and revert back to “Normal” for state description

* Fix Travis error
2017-12-05 23:05:30 -08:00

351 lines
9.3 KiB
HTML

<script src='../../bower_components/fecha/fecha.min.js'></script>
<script src='../../build-temp/util.js'></script>
<!--
collection of utility functions.
-->
<script>
window.hassUtil = window.hassUtil || {};
window.hassUtil.DEFAULT_ICON = 'mdi:bookmark';
window.hassUtil.OFF_STATES = ['off', 'closed', 'unlocked'];
window.hassUtil.DOMAINS_WITH_NO_HISTORY = ['camera', 'configurator', 'history_graph', 'scene'];
// Update root's child element to be newElementTag replacing another existing child if any.
// Copy attributes into the child element.
window.hassUtil.dynamicContentUpdater = function (root, newElementTag, attributes) {
var rootEl = Polymer.dom(root);
var customEl;
if (rootEl.lastChild && rootEl.lastChild.tagName === newElementTag) {
customEl = rootEl.lastChild;
} else {
if (rootEl.lastChild) {
rootEl.removeChild(rootEl.lastChild);
}
// Creating an element with upper case works fine in Chrome, but in FF it doesn't immediately
// become a defined Custom Element. Polymer does that in some later pass.
customEl = document.createElement(newElementTag.toLowerCase());
}
if (customEl.setProperties) {
customEl.setProperties(attributes);
} else {
// If custom element definition wasn't loaded yet - setProperties would be
// missing, but no harm in setting attributes one-by-one then.
Object.keys(attributes).forEach((key) => {
customEl[key] = attributes[key];
});
}
if (customEl.parentNode === null) {
rootEl.appendChild(customEl);
}
};
window.hassUtil.relativeTime = function (dateObj) {
var delta = Math.abs(new Date() - dateObj) / 1000;
var format = new Date() > dateObj ? '%s ago' : 'in %s';
var tests = window.hassUtil.relativeTime.tests;
var i;
for (i = 0; i < tests.length; i += 2) {
if (delta < tests[i]) {
delta = Math.floor(delta);
return format.replace(
'%s',
delta === 1 ? '1 ' + tests[i + 1] : delta + ' ' + tests[i + 1] + 's'
);
}
delta /= tests[i];
}
delta = Math.floor(delta);
return format.replace('%s', delta === 1 ? '1 week' : delta + ' weeks');
};
window.hassUtil.relativeTime.tests = [
60, 'second',
60, 'minute',
24, 'hour',
7, 'day',
];
window.hassUtil.domainIcon = function (domain, state) {
switch (domain) {
case 'alarm_control_panel':
return state && state === 'disarmed' ? 'mdi:bell-outline' : 'mdi:bell';
case 'automation':
return 'mdi:playlist-play';
case 'binary_sensor':
return state && state === 'off' ? 'mdi:radiobox-blank' : 'mdi:checkbox-marked-circle';
case 'calendar':
return 'mdi:calendar';
case 'camera':
return 'mdi:video';
case 'climate':
return 'mdi:nest-thermostat';
case 'configurator':
return 'mdi:settings';
case 'conversation':
return 'mdi:text-to-speech';
case 'cover':
return state && state === 'open' ? 'mdi:window-open' : 'mdi:window-closed';
case 'device_tracker':
return 'mdi:account';
case 'fan':
return 'mdi:fan';
case 'history_graph':
return 'mdi:chart-line';
case 'group':
return 'mdi:google-circles-communities';
case 'homeassistant':
return 'mdi:home';
case 'image_processing':
return 'mdi:image-filter-frames';
case 'input_boolean':
return 'mdi:drawing';
case 'input_datetime':
return 'mdi:calendar-clock';
case 'input_select':
return 'mdi:format-list-bulleted';
case 'input_number':
return 'mdi:ray-vertex';
case 'input_text':
return 'mdi:textbox';
case 'light':
return 'mdi:lightbulb';
case 'lock':
return state && state === 'unlocked' ? 'mdi:lock-open' : 'mdi:lock';
case 'mailbox':
return 'mdi:mailbox';
case 'media_player':
return state && state !== 'off' && state !== 'idle' ?
'mdi:cast-connected' : 'mdi:cast';
case 'notify':
return 'mdi:comment-alert';
case 'proximity':
return 'mdi:apple-safari';
case 'remote':
return 'mdi:remote';
case 'scene':
return 'mdi:google-pages';
case 'script':
return 'mdi:file-document';
case 'sensor':
return 'mdi:eye';
case 'simple_alarm':
return 'mdi:bell';
case 'sun':
return 'mdi:white-balance-sunny';
case 'switch':
return 'mdi:flash';
case 'updater':
return 'mdi:cloud-upload';
case 'weblink':
return 'mdi:open-in-new';
case 'zwave':
switch (state) {
case 'dead':
return 'mdi:emoticon-dead';
case 'sleeping':
return 'mdi:sleep';
case 'initializing':
return 'mdi:timer-sand';
default:
return 'mdi:nfc';
}
default:
/* eslint-disable no-console */
console.warn('Unable to find icon for domain ' + domain + ' (' + state + ')');
/* eslint-enable no-console */
return window.hassUtil.DEFAULT_ICON;
}
};
window.hassUtil.binarySensorIcon = function (state) {
var activated = state.state && state.state === 'off';
switch (state.attributes.device_class) {
case 'battery':
return activated ? 'mdi:battery' : 'mdi:battery-outline';
case 'connectivity':
return activated ? 'mdi:server-network-off' : 'mdi:server-network';
case 'light':
return activated ? 'mdi:brightness-5' : 'mdi:brightness-7';
case 'moisture':
return activated ? 'mdi:water-off' : 'mdi:water';
case 'motion':
return activated ? 'mdi:walk' : 'mdi:run';
case 'occupancy':
return activated ? 'mdi:home' : 'mdi:home-outline';
case 'opening':
return activated ? 'mdi:door-closed' : 'mdi:door-open';
case 'sound':
return activated ? 'mdi:music-note-off' : 'mdi:music-note';
case 'vibration':
return activated ? 'mdi:crop-portrait' : 'mdi:vibrate';
case 'gas':
case 'power':
case 'safety':
case 'smoke':
return activated ? 'mdi:verified' : 'mdi:alert';
case 'plug':
return activated ? 'mdi:power-plug-off' : 'mdi:power-plug';
case 'presence':
return activated ? 'mdi:home-outline' : 'mdi:home';
default:
return activated ? 'mdi:radiobox-blank' : 'mdi:checkbox-marked-circle';
}
};
window.hassUtil.coverIcon = function (state) {
var open = state.state && state.state === 'open';
switch (state.attributes.device_class) {
case 'garage':
return open ? 'mdi:garage-open' : 'mdi:garage';
default:
return open ? 'mdi:window-open' : 'mdi:window-closed';
}
};
window.hassUtil.stateIcon = function (state) {
if (!state) {
return window.hassUtil.DEFAULT_ICON;
} else if (state.attributes.icon) {
return state.attributes.icon;
}
var unit = state.attributes.unit_of_measurement;
var domain = window.hassUtil.computeDomain(state);
if (unit && domain === 'sensor') {
if (unit === '°C' || unit === '°F') {
return 'mdi:thermometer';
} else if (unit === 'Mice') {
return 'mdi:mouse-variant';
}
} else if (domain === 'binary_sensor') {
return window.hassUtil.binarySensorIcon(state);
} else if (domain === 'cover') {
return window.hassUtil.coverIcon(state);
} else if (domain === 'input_datetime') {
if (!state.attributes.has_date) {
return 'mdi:clock';
} else if (!state.attributes.has_time) {
return 'mdi:calendar';
}
}
return window.hassUtil.domainIcon(domain, state.state);
};
window.hassUtil.computeObjectId = function (stateObj) {
if (!stateObj._object_id) {
stateObj._object_id = window.HAWS.extractObjectId(stateObj.entity_id);
}
return stateObj._object_id;
};
window.hassUtil.computeStateName = function (stateObj) {
if (stateObj._entityDisplay === undefined) {
stateObj._entityDisplay = (
stateObj.attributes.friendly_name ||
window.HAWS.extractObjectId(stateObj.entity_id)
.replace(/_/g, ' '));
}
return stateObj._entityDisplay;
};
window.hassUtil.sortByName = function (entityA, entityB) {
var nameA = window.hassUtil.computeStateName(entityA);
var nameB = window.hassUtil.computeStateName(entityB);
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
return 0;
};
window.hassUtil.isComponentLoaded = function (hass, component) {
return hass && hass.config.core.components.indexOf(component) !== -1;
};
window.hassUtil.computeLocationName = function (hass) {
return hass && hass.config.core.location_name;
};
window.hassUtil.applyThemesOnElement = function (element, themes, localTheme, updateMeta) {
if (!element._themes) {
element._themes = {};
}
let themeName = themes.default_theme;
if (localTheme === 'default' || (localTheme && themes.themes[localTheme])) {
themeName = localTheme;
}
const styles = Object.assign({}, element._themes);
if (themeName !== 'default') {
var theme = themes.themes[themeName];
Object.keys(theme).forEach((key) => {
var prefixedKey = '--' + key;
element._themes[prefixedKey] = '';
styles[prefixedKey] = theme[key];
});
}
element.updateStyles(styles);
if (!updateMeta) return;
const meta = document.querySelector('meta[name=theme-color]');
if (meta) {
if (!meta.hasAttribute('default-content')) {
meta.setAttribute('default-content', meta.getAttribute('content'));
}
const themeColor = styles['--primary-color'] || meta.getAttribute('default-content');
meta.setAttribute('content', themeColor);
}
};
</script>