UNPKG

@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
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