mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
parent
05d7b98ba0
commit
a48aa3c778
@ -420,15 +420,6 @@ export default {
|
||||
last_changed: "2018-07-19T10:44:46.105940+00:00",
|
||||
last_updated: "2018-07-19T10:44:46.105940+00:00",
|
||||
},
|
||||
"weblink.router": {
|
||||
entity_id: "weblink.router",
|
||||
state: "http://192.168.1.1",
|
||||
attributes: {
|
||||
friendly_name: "Router",
|
||||
},
|
||||
last_changed: "2018-07-19T10:44:46.107286+00:00",
|
||||
last_updated: "2018-07-19T10:44:46.107286+00:00",
|
||||
},
|
||||
"group.all_plants": {
|
||||
entity_id: "group.all_plants",
|
||||
state: "ok",
|
||||
@ -1090,18 +1081,6 @@ export default {
|
||||
last_changed: "2018-07-19T10:44:46.510448+00:00",
|
||||
last_updated: "2018-07-19T10:44:46.510448+00:00",
|
||||
},
|
||||
"history_graph.recent_switches": {
|
||||
entity_id: "history_graph.recent_switches",
|
||||
state: "unknown",
|
||||
attributes: {
|
||||
hours_to_show: 1,
|
||||
refresh: 60,
|
||||
entity_id: ["switch.ac", "switch.decorative_lights"],
|
||||
friendly_name: "Recent Switches",
|
||||
},
|
||||
last_changed: "2018-07-19T10:44:46.512351+00:00",
|
||||
last_updated: "2018-07-19T10:44:46.512351+00:00",
|
||||
},
|
||||
"scene.switch_on_and_off": {
|
||||
entity_id: "scene.switch_on_and_off",
|
||||
state: "scening",
|
||||
|
@ -1,131 +0,0 @@
|
||||
import "@polymer/paper-card/paper-card";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import "../components/state-history-charts";
|
||||
import "../data/ha-state-history-data";
|
||||
import { EventsMixin } from "../mixins/events-mixin";
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
*/
|
||||
class HaHistoryGraphCard extends EventsMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
paper-card:not([dialog]) .content {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
paper-card[dialog] {
|
||||
padding-top: 16px;
|
||||
background-color: transparent;
|
||||
}
|
||||
paper-card {
|
||||
width: 100%;
|
||||
/* prevent new stacking context, chart tooltip needs to overflow */
|
||||
position: static;
|
||||
}
|
||||
.header {
|
||||
@apply --paper-font-headline;
|
||||
line-height: 40px;
|
||||
color: var(--primary-text-color);
|
||||
padding: 20px 16px 12px;
|
||||
@apply --paper-font-common-nowrap;
|
||||
}
|
||||
paper-card[dialog] .header {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<ha-state-history-data
|
||||
hass="[[hass]]"
|
||||
filter-type="recent-entity"
|
||||
entity-id="[[computeHistoryEntities(stateObj)]]"
|
||||
data="{{stateHistory}}"
|
||||
is-loading="{{stateHistoryLoading}}"
|
||||
cache-config="[[cacheConfig]]"
|
||||
></ha-state-history-data>
|
||||
<paper-card
|
||||
dialog$="[[inDialog]]"
|
||||
on-click="cardTapped"
|
||||
elevation="[[computeElevation(inDialog)]]"
|
||||
>
|
||||
<div class="header">[[computeTitle(stateObj)]]</div>
|
||||
<div class="content">
|
||||
<state-history-charts
|
||||
hass="[[hass]]"
|
||||
history-data="[[stateHistory]]"
|
||||
is-loading-data="[[stateHistoryLoading]]"
|
||||
up-to-now
|
||||
no-single
|
||||
>
|
||||
</state-history-charts>
|
||||
</div>
|
||||
</paper-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
stateObj: {
|
||||
type: Object,
|
||||
observer: "stateObjObserver",
|
||||
},
|
||||
inDialog: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
stateHistory: Object,
|
||||
stateHistoryLoading: Boolean,
|
||||
cacheConfig: {
|
||||
type: Object,
|
||||
value: {
|
||||
refresh: 0,
|
||||
cacheKey: null,
|
||||
hoursToShow: 24,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
stateObjObserver(stateObj) {
|
||||
if (!stateObj) return;
|
||||
if (
|
||||
this.cacheConfig.cacheKey !== stateObj.entity_id ||
|
||||
this.cacheConfig.refresh !== (stateObj.attributes.refresh || 0) ||
|
||||
this.cacheConfig.hoursToShow !== (stateObj.attributes.hours_to_show || 24)
|
||||
) {
|
||||
this.cacheConfig = {
|
||||
refresh: stateObj.attributes.refresh || 0,
|
||||
cacheKey: stateObj.entity_id,
|
||||
hoursToShow: stateObj.attributes.hours_to_show || 24,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
computeTitle(stateObj) {
|
||||
return computeStateName(stateObj);
|
||||
}
|
||||
|
||||
computeContentClass(inDialog) {
|
||||
return inDialog ? "" : "content";
|
||||
}
|
||||
|
||||
computeHistoryEntities(stateObj) {
|
||||
return stateObj.attributes.entity_id;
|
||||
}
|
||||
|
||||
computeElevation(inDialog) {
|
||||
return inDialog ? 0 : 1;
|
||||
}
|
||||
|
||||
cardTapped(ev) {
|
||||
const mq = window.matchMedia("(min-width: 610px) and (min-height: 550px)");
|
||||
if (mq.matches) {
|
||||
ev.stopPropagation();
|
||||
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
||||
}
|
||||
}
|
||||
}
|
||||
customElements.define("ha-history_graph-card", HaHistoryGraphCard);
|
@ -22,7 +22,6 @@ export const DOMAINS_WITH_CARD = [
|
||||
"timer",
|
||||
"vacuum",
|
||||
"water_heater",
|
||||
"weblink",
|
||||
];
|
||||
|
||||
/** Domains with separate more info dialog. */
|
||||
@ -36,7 +35,6 @@ export const DOMAINS_WITH_MORE_INFO = [
|
||||
"cover",
|
||||
"fan",
|
||||
"group",
|
||||
"history_graph",
|
||||
"humidifier",
|
||||
"input_datetime",
|
||||
"light",
|
||||
@ -58,16 +56,10 @@ export const DOMAINS_HIDE_MORE_INFO = [
|
||||
"input_select",
|
||||
"input_text",
|
||||
"scene",
|
||||
"weblink",
|
||||
];
|
||||
|
||||
/** Domains that should have the history hidden in the more info dialog. */
|
||||
export const DOMAINS_MORE_INFO_NO_HISTORY = [
|
||||
"camera",
|
||||
"configurator",
|
||||
"history_graph",
|
||||
"scene",
|
||||
];
|
||||
export const DOMAINS_MORE_INFO_NO_HISTORY = ["camera", "configurator", "scene"];
|
||||
|
||||
/** States that we consider "off". */
|
||||
export const STATES_OFF = ["closed", "locked", "off"];
|
||||
|
@ -20,7 +20,6 @@ const fixedIcons = {
|
||||
fan: "hass:fan",
|
||||
google_assistant: "hass:google-assistant",
|
||||
group: "hass:google-circles-communities",
|
||||
history_graph: "hass:chart-line",
|
||||
homeassistant: "hass:home-assistant",
|
||||
homekit: "hass:home-automation",
|
||||
humidifier: "hass:air-humidifier",
|
||||
@ -49,7 +48,6 @@ const fixedIcons = {
|
||||
vacuum: "hass:robot-vacuum",
|
||||
water_heater: "hass:thermometer",
|
||||
weather: "hass:weather-cloudy",
|
||||
weblink: "hass:open-in-new",
|
||||
zone: "hass:map-marker-radius",
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,6 @@ export const ENTITY_COMPONENT_DOMAINS = [
|
||||
"fan",
|
||||
"geo_location",
|
||||
"group",
|
||||
"history_graph",
|
||||
"image_processing",
|
||||
"input_boolean",
|
||||
"input_datetime",
|
||||
|
@ -1,178 +0,0 @@
|
||||
import { timeOut } from "@polymer/polymer/lib/utils/async";
|
||||
import { Debouncer } from "@polymer/polymer/lib/utils/debounce";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import LocalizeMixin from "../mixins/localize-mixin";
|
||||
import { getRecent, getRecentWithCache } from "./cached-history";
|
||||
import { computeHistory, fetchDate } from "./history";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class HaStateHistoryData extends LocalizeMixin(PolymerElement) {
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
observer: "hassChanged",
|
||||
},
|
||||
|
||||
filterType: String,
|
||||
|
||||
cacheConfig: Object,
|
||||
|
||||
startTime: Date,
|
||||
endTime: Date,
|
||||
|
||||
entityId: String,
|
||||
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
readOnly: true,
|
||||
notify: true,
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object,
|
||||
value: null,
|
||||
readOnly: true,
|
||||
notify: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return [
|
||||
"filterChangedDebouncer(filterType, entityId, startTime, endTime, cacheConfig, localize)",
|
||||
];
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.filterChangedDebouncer(
|
||||
this.filterType,
|
||||
this.entityId,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.cacheConfig,
|
||||
this.localize
|
||||
);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
if (this._refreshTimeoutId) {
|
||||
window.clearInterval(this._refreshTimeoutId);
|
||||
this._refreshTimeoutId = null;
|
||||
}
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
hassChanged(newHass, oldHass) {
|
||||
if (!oldHass && !this._madeFirstCall) {
|
||||
this.filterChangedDebouncer(
|
||||
this.filterType,
|
||||
this.entityId,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
this.cacheConfig,
|
||||
this.localize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
filterChangedDebouncer(...args) {
|
||||
this._debounceFilterChanged = Debouncer.debounce(
|
||||
this._debounceFilterChanged,
|
||||
timeOut.after(0),
|
||||
() => {
|
||||
this.filterChanged(...args);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
filterChanged(
|
||||
filterType,
|
||||
entityId,
|
||||
startTime,
|
||||
endTime,
|
||||
cacheConfig,
|
||||
localize
|
||||
) {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
if (cacheConfig && !cacheConfig.cacheKey) {
|
||||
return;
|
||||
}
|
||||
if (!localize) {
|
||||
return;
|
||||
}
|
||||
this._madeFirstCall = true;
|
||||
const language = this.hass.language;
|
||||
let data;
|
||||
|
||||
if (filterType === "date") {
|
||||
if (!startTime || !endTime) return;
|
||||
|
||||
data = fetchDate(this.hass, startTime, endTime).then((dateHistory) =>
|
||||
computeHistory(this.hass, dateHistory, localize, language)
|
||||
);
|
||||
} else if (filterType === "recent-entity") {
|
||||
if (!entityId) return;
|
||||
if (cacheConfig) {
|
||||
data = this.getRecentWithCacheRefresh(
|
||||
entityId,
|
||||
cacheConfig,
|
||||
localize,
|
||||
language
|
||||
);
|
||||
} else {
|
||||
data = getRecent(
|
||||
this.hass,
|
||||
entityId,
|
||||
startTime,
|
||||
endTime,
|
||||
localize,
|
||||
language
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
this._setIsLoading(true);
|
||||
|
||||
data.then((stateHistory) => {
|
||||
this._setData(stateHistory);
|
||||
this._setIsLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
getRecentWithCacheRefresh(entityId, cacheConfig, localize, language) {
|
||||
if (this._refreshTimeoutId) {
|
||||
window.clearInterval(this._refreshTimeoutId);
|
||||
this._refreshTimeoutId = null;
|
||||
}
|
||||
if (cacheConfig.refresh) {
|
||||
this._refreshTimeoutId = window.setInterval(() => {
|
||||
getRecentWithCache(
|
||||
this.hass,
|
||||
entityId,
|
||||
cacheConfig,
|
||||
localize,
|
||||
language
|
||||
).then((stateHistory) => {
|
||||
this._setData({ ...stateHistory });
|
||||
});
|
||||
}, cacheConfig.refresh * 1000);
|
||||
}
|
||||
return getRecentWithCache(
|
||||
this.hass,
|
||||
entityId,
|
||||
cacheConfig,
|
||||
localize,
|
||||
language
|
||||
);
|
||||
}
|
||||
}
|
||||
customElements.define("ha-state-history-data", HaStateHistoryData);
|
@ -1,33 +0,0 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import "../../../cards/ha-history_graph-card";
|
||||
import "../../../components/ha-attributes";
|
||||
|
||||
class MoreInfoHistoryGraph extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
</style>
|
||||
<ha-history_graph-card
|
||||
hass="[[hass]]"
|
||||
state-obj="[[stateObj]]"
|
||||
in-dialog=""
|
||||
>
|
||||
<ha-attributes state-obj="[[stateObj]]"></ha-attributes>
|
||||
</ha-history_graph-card>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
stateObj: Object,
|
||||
};
|
||||
}
|
||||
}
|
||||
customElements.define("more-info-history_graph", MoreInfoHistoryGraph);
|
@ -29,7 +29,7 @@ import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { mdiClose, mdiCog, mdiPencil } from "@mdi/js";
|
||||
import { HistoryResult } from "../../data/history";
|
||||
|
||||
const DOMAINS_NO_INFO = ["camera", "configurator", "history_graph"];
|
||||
const DOMAINS_NO_INFO = ["camera", "configurator"];
|
||||
const EDITABLE_DOMAINS_WITH_ID = ["scene", "automation"];
|
||||
const EDITABLE_DOMAINS = ["script"];
|
||||
|
||||
@ -288,7 +288,6 @@ export class MoreInfoDialog extends LitElement {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
ha-dialog[data-domain="history_graph"] .content,
|
||||
:host([large]) .content {
|
||||
width: calc(90vw - 48px);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import "./controls/more-info-cover";
|
||||
import "./controls/more-info-default";
|
||||
import "./controls/more-info-fan";
|
||||
import "./controls/more-info-group";
|
||||
import "./controls/more-info-history_graph";
|
||||
import "./controls/more-info-humidifier";
|
||||
import "./controls/more-info-input_datetime";
|
||||
import "./controls/more-info-light";
|
||||
|
@ -148,7 +148,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
private async _getStateHistory(): Promise<void> {
|
||||
this._stateHistory = getRecentWithCache(
|
||||
this._stateHistory = await getRecentWithCache(
|
||||
this.hass!,
|
||||
this._cacheConfig!.cacheKey,
|
||||
this._cacheConfig!,
|
||||
|
@ -43,7 +43,7 @@ import {
|
||||
ThermostatCardConfig,
|
||||
} from "../cards/types";
|
||||
import { processEditorEntities } from "../editor/process-editor-entities";
|
||||
import { LovelaceRowConfig, WeblinkConfig } from "../entity-rows/types";
|
||||
import { LovelaceRowConfig } from "../entity-rows/types";
|
||||
|
||||
const DEFAULT_VIEW_ENTITY_ID = "group.default_view";
|
||||
const DOMAINS_BADGES = [
|
||||
@ -143,15 +143,6 @@ export const computeCards = (
|
||||
entity: entityId,
|
||||
};
|
||||
cards.push(cardConfig);
|
||||
} else if (domain === "history_graph" && stateObj) {
|
||||
const cardConfig = {
|
||||
type: "history-graph",
|
||||
entities: stateObj.attributes.entity_id,
|
||||
hours_to_show: stateObj.attributes.hours_to_show,
|
||||
title: stateObj.attributes.friendly_name,
|
||||
refresh_interval: stateObj.attributes.refresh,
|
||||
};
|
||||
cards.push(cardConfig);
|
||||
} else if (domain === "humidifier") {
|
||||
const cardConfig: HumidifierCardConfig = {
|
||||
type: "humidifier",
|
||||
@ -182,15 +173,6 @@ export const computeCards = (
|
||||
entity: entityId,
|
||||
};
|
||||
cards.push(cardConfig);
|
||||
} else if (domain === "weblink" && stateObj) {
|
||||
const conf: WeblinkConfig = {
|
||||
type: "weblink",
|
||||
url: stateObj.state,
|
||||
};
|
||||
if ("icon" in stateObj.attributes) {
|
||||
conf.icon = stateObj.attributes.icon;
|
||||
}
|
||||
entities.push(conf);
|
||||
} else if (
|
||||
domain === "sensor" &&
|
||||
stateObj?.attributes.device_class === SENSOR_DEVICE_CLASS_BATTERY
|
||||
|
@ -17,7 +17,6 @@ import "./state-card-timer";
|
||||
import "./state-card-toggle";
|
||||
import "./state-card-vacuum";
|
||||
import "./state-card-water_heater";
|
||||
import "./state-card-weblink";
|
||||
|
||||
class StateCardContent extends PolymerElement {
|
||||
static get properties() {
|
||||
|
@ -1,61 +0,0 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import "../components/entity/state-badge";
|
||||
|
||||
class StateCardWeblink extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
.name {
|
||||
@apply --paper-font-common-nowrap;
|
||||
@apply --paper-font-body1;
|
||||
color: var(--primary-color);
|
||||
|
||||
text-transform: capitalize;
|
||||
line-height: 40px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
${this.stateBadgeTemplate}
|
||||
<a href$="[[stateObj.state]]" target="_blank" class="name" id="link"
|
||||
>[[_computeStateName(stateObj)]]</a
|
||||
>
|
||||
`;
|
||||
}
|
||||
|
||||
static get stateBadgeTemplate() {
|
||||
return html` <state-badge state-obj="[[stateObj]]"></state-badge> `;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
stateObj: Object,
|
||||
inDialog: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.addEventListener("click", (ev) => this.onTap(ev));
|
||||
}
|
||||
|
||||
_computeStateName(stateObj) {
|
||||
return computeStateName(stateObj);
|
||||
}
|
||||
|
||||
onTap(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
window.open(this.stateObj.state, "_blank");
|
||||
}
|
||||
}
|
||||
customElements.define("state-card-weblink", StateCardWeblink);
|
Loading…
x
Reference in New Issue
Block a user