UNPKG

openhab

Version:
111 lines (99 loc) 3.21 kB
const time = require('../time'); const { _isInstant } = require('../helpers'); /** * @typedef { import('@js-joda/core').Instant} time.Instant * @private */ /** * @typedef { import('@js-joda/core').ZonedDateTime} time.ZonedDateTime * @private */ /** * @typedef {import('../quantity').Quantity} Quantity * @private */ /** * A TimeSeries is used to transport a set of states together with their timestamp. * It is usually used for persisting historic state or forecasts in a persistence service. * * @memberof items */ class TimeSeries { #states = []; #policy; /** * Creates a new TimeSeries. * * The TimeSeries policy defines how the TimeSeries is persisted in a persistence service: * <code>ADD</code> adds the content to the persistence, * <code>REPLACE</code> first removes all persisted elements in the timespan given by {@link begin} and {@link end}. * * @param {string} policy TimeSeries policy <code>ADD</code> or <code>REPLACE</code> */ constructor (policy) { if (!['ADD', 'REPLACE'].includes(policy)) throw new TypeError(`Invalid TimeSeries policy: ${policy}. Expected 'ADD' or 'REPLACE'.`); this.#policy = policy; } /** * The persistence policy of this TimeSeries * * @type {string} */ get policy () { return this.#policy; } /** * Timestamp of the first element in the TimeSeries * @type {time.Instant} */ get begin () { return this.#states.reduce((min, [timestamp, state]) => min.isBefore(timestamp) ? min : timestamp, time.Instant.MAX); } /** * Timestamp of the last element in the TimeSeries * @type {time.Instant} */ get end () { return this.#states.reduce((max, [timestamp, state]) => max.isAfter(timestamp) ? max : timestamp, time.Instant.MIN); } /** * Number of elements in the TimeSeries * @type {number} */ get size () { return this.#states.length; } /** * States of the TimeSeries together with their timestamp and sorted by their timestamps * * Be aware that this method returns a reference to the internal state array, so changes to the array will affect the TimeSeries. * * @type {Array} */ get states () { return this.#states.sort(([timestampA, stateA], [timestampB, stateB]) => timestampA.isBefore(timestampB) ? -1 : 1); } /** * Add a new element to the TimeSeries. * * Elements can be added in an arbitrary order and are sorted chronologically. * * @param {(time.Instant|time.ZonedDateTime|string|Date)} timestamp a timestamp for the given state * @param {string|number|Quantity|HostState} state the state at the given timestamp * @returns {TimeSeries} this TimeSeries instance */ add (timestamp, state) { const ts = _isInstant(timestamp) ? timestamp : time.toZDT(timestamp).toInstant(); this.#states.push([ts, state]); return this; } toString () { let states = ''; for (const [timestamp, state] of this.states) { states += `[${timestamp} -> ${state}], `; } states = states.substring(0, states.length - 2); return `TimeSeries (Begin=${this.begin}, End=${this.end}, Size=${this.size}, States=${states})`; } } module.exports = TimeSeries;