@hakit/core
Version:
A collection of React hooks and helpers for Home Assistant to easily communicate with the Home Assistant WebSocket API.
153 lines (152 loc) • 5.56 kB
JavaScript
import "lodash";
import "../../utils/light/index.js";
import { computeDomain as f } from "../../utils/computeDomain.js";
import { l as y } from "../../../index-BfdcdUoC.js";
import "../../HassConnect/HassContext.js";
import "react";
import "@iconify/react";
import "use-debounce";
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 = (i) => i.substr(i.indexOf(".") + 1), b = (i, s) => s?.friendly_name === void 0 ? S(i).replace(/_/g, " ") : s.friendly_name || "", E = (i) => H.includes(f(i)), L = ({
connection: i,
entityIds: s,
callbackFunction: n,
hoursToShow: e = 24,
minimalResponse: t = !0,
significantChangesOnly: r = !0,
noAttributes: o
}) => {
const u = {
type: "history/stream",
entity_ids: s,
start_time: new Date((/* @__PURE__ */ new Date()).getTime() - 3600 * e * 1e3).toISOString(),
minimal_response: t,
significant_changes_only: r,
no_attributes: o ?? !s.some((l) => E(l))
}, a = new T(i, e);
return i.subscribeMessage((l) => n(a.processMessage(l)), u);
};
class T {
connection;
hoursToShow;
combinedHistory;
constructor(s, n) {
this.connection = s, this.hoursToShow = n, this.combinedHistory = {};
}
processMessage(s) {
if (!this.combinedHistory || !Object.keys(this.combinedHistory).length)
return this.combinedHistory = s.states, this.combinedHistory;
if (!Object.keys(s.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(s.states))
e[t] = [];
for (const t of Object.keys(e)) {
if (t in this.combinedHistory && t in s.states) {
const r = this.combinedHistory[t], o = r[r.length - 1];
e[t] = r.concat(s.states[t]), s.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] = s.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 = (i, s) => i.state === s.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.
(!i.attributes || !s.attributes || _.every((n) => i.attributes[n] === s.attributes[n])), O = (i, s, n) => {
const e = [];
return Object.keys(s).forEach((t) => {
const r = s[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: i,
identifier: Object.keys(n).join(""),
data: e
};
}, w = (i, s, n) => {
const e = [], t = s[0];
for (const r of s)
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(i, n?.attributes || t.a),
entity_id: i,
data: e
};
}, D = (i) => p(i.attributes), p = (i) => "unit_of_measurement" in i || "state_class" in i, P = (i, s, n) => {
const e = {}, t = [];
return n ? (Object.keys(n).forEach((o) => {
const u = n[o];
if (u.length === 0)
return;
const a = o in s ? s[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: i.unit_system.temperature,
counter: "#",
humidifier: "%",
input_number: "#",
number: "#",
water_heater: i.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], s)), timeline: t }) : { line: [], timeline: [] };
};
export {
P as computeHistory,
S as computeObjectId,
b as computeStateNameFromEntityAttributes,
E as entityIdHistoryNeedsAttributes,
L as subscribeHistory
};
//# sourceMappingURL=history.js.map