@hakit/core
Version:
A collection of React hooks and helpers for Home Assistant to easily communicate with the Home Assistant WebSocket API.
154 lines (153 loc) • 5.59 kB
JavaScript
import "lodash";
import "../../utils/light/index.js";
import { computeDomain as f } from "../../utils/computeDomain.js";
import { l as y } from "../../../index-DnHwXFlq.js";
import "../../HassConnect/HassContext.js";
import "react";
import "@iconify/react";
import "use-debounce";
import "deep-object-diff";
import "home-assistant-js-websocket";
import "../useLocale/locales/index.js";
const g = ["climate", "humidifier", "water_heater"], H = ["climate", "humidifier", "input_datetime", "thermostat", "water_heater", "person", "device_tracker"], _ = [
"temperature",
"current_temperature",
"target_temp_low",
"target_temp_high",
"hvac_action",
"humidity",
"mode",
"action",
"current_humidity"
], S = (s) => s.substr(s.indexOf(".") + 1), b = (s, i) => i?.friendly_name === void 0 ? S(s).replace(/_/g, " ") : i.friendly_name || "", E = (s) => H.includes(f(s)), P = ({
connection: s,
entityIds: i,
callbackFunction: n,
hoursToShow: e = 24,
minimalResponse: t = !0,
significantChangesOnly: r = !0,
noAttributes: o
}) => {
const u = {
type: "history/stream",
entity_ids: i,
start_time: new Date((/* @__PURE__ */ new Date()).getTime() - 3600 * e * 1e3).toISOString(),
minimal_response: t,
significant_changes_only: r,
no_attributes: o ?? !i.some((l) => E(l))
}, a = new T(s, e);
return s.subscribeMessage((l) => n(a.processMessage(l)), u);
};
class T {
connection;
hoursToShow;
combinedHistory;
constructor(i, n) {
this.connection = i, this.hoursToShow = n, this.combinedHistory = {};
}
processMessage(i) {
if (!this.combinedHistory || !Object.keys(this.combinedHistory).length)
return this.combinedHistory = i.states, this.combinedHistory;
if (!Object.keys(i.states).length)
return this.combinedHistory;
const n = this.hoursToShow ? ((/* @__PURE__ */ new Date()).getTime() - 60 * 60 * this.hoursToShow * 1e3) / 1e3 : void 0, e = {};
for (const t of Object.keys(this.combinedHistory))
e[t] = [];
for (const t of Object.keys(i.states))
e[t] = [];
for (const t of Object.keys(e)) {
if (t in this.combinedHistory && t in i.states) {
const r = this.combinedHistory[t], o = r[r.length - 1];
e[t] = r.concat(i.states[t]), i.states[t][0].lu < o.lu && (e[t] = e[t].sort((u, a) => u.lu - a.lu));
} else t in this.combinedHistory ? e[t] = this.combinedHistory[t] : e[t] = i.states[t];
if (n && t in this.combinedHistory) {
const r = e[t].filter((u) => u.lu < n);
if (!r.length || (e[t] = e[t].filter((u) => u.lu >= n), e[t].length && e[t][0].lu === n))
continue;
const o = r[r.length - 1];
o.lu = n, e[t].unshift(o);
}
}
return this.combinedHistory = e, this.combinedHistory;
}
}
const d = (s, i) => s.state === i.state && // Only compare attributes if both states have an attributes object.
// When `minimal_response` is sent, only the first and last state
// will have attributes except for domains in DOMAINS_USE_LAST_UPDATED.
(!s.attributes || !i.attributes || _.every((n) => s.attributes[n] === i.attributes[n])), O = (s, i, n) => {
const e = [];
return Object.keys(i).forEach((t) => {
const r = i[t], o = r[0], u = f(t), a = [];
for (const c of r) {
let m;
if (g.includes(u)) {
m = {
state: c.s,
last_changed: c.lu * 1e3,
attributes: {}
};
for (const h of _)
h in c.a && (m.attributes[h] = c.a[h]);
} else
m = {
state: c.s,
// lc (last_changed) may be omitted if its the same
// as lu (last_updated).
last_changed: (c.lc ? c.lc : c.lu) * 1e3,
attributes: {}
};
a.length > 1 && d(m, a[a.length - 1]) && d(m, a[a.length - 2]) || a.push(m);
}
const l = t in n ? n[t].attributes : "friendly_name" in o.a ? o.a : void 0;
e.push({
domain: u,
name: b(t, l || {}),
entity_id: t,
states: a
});
}), {
unit: s,
identifier: Object.keys(n).join(""),
data: e
};
}, w = (s, i, n) => {
const e = [], t = i[0];
for (const r of i)
e.length > 0 && r.s === e[e.length - 1].state || (n?.attributes.device_class && n?.attributes.device_class, e.push({
state: r.s,
// lc (last_changed) may be omitted if its the same
// as lu (last_updated).
last_changed: (r.lc ? r.lc : r.lu) * 1e3
}));
return {
name: b(s, n?.attributes || t.a),
entity_id: s,
data: e
};
}, D = (s) => p(s.attributes), p = (s) => "unit_of_measurement" in s || "state_class" in s, R = (s, i, n) => {
const e = {}, t = [];
return n ? (Object.keys(n).forEach((o) => {
const u = n[o];
if (u.length === 0)
return;
const a = o in i ? i[o] : void 0, l = !a && u.find((m) => m.a && p(m.a));
let c;
a && D(a) ? c = a.attributes.unit_of_measurement || " " : l ? c = l.a.unit_of_measurement || " " : c = {
zone: y("people_in_zone"),
climate: s.unit_system.temperature,
counter: "#",
humidifier: "%",
input_number: "#",
number: "#",
water_heater: s.unit_system.temperature
}[f(o)], c ? c in e && o in e[c] ? e[c][o].push(...u) : (c in e || (e[c] = {}), e[c][o] = u) : t.push(w(o, u, a));
}), { line: Object.keys(e).map((o) => O(o, e[o], i)), timeline: t }) : { line: [], timeline: [] };
};
export {
R as computeHistory,
S as computeObjectId,
b as computeStateNameFromEntityAttributes,
E as entityIdHistoryNeedsAttributes,
P as subscribeHistory
};
//# sourceMappingURL=history.js.map