diff --git a/.devcontainer/ui-lovelace.yaml b/.devcontainer/ui-lovelace.yaml index f3fc215..a47b4cc 100644 --- a/.devcontainer/ui-lovelace.yaml +++ b/.devcontainer/ui-lovelace.yaml @@ -193,8 +193,9 @@ views: curve: smooth name: FIRST type: line - # show: - # as_duration: year + show: + as_duration: year + in_header: raw group_by: duration: 10min func: first diff --git a/README.md b/README.md index 658f7de..9a13a60 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ The card stricly validates all the options available (but not for the `apex_conf | ---- | :--: | :-----: | :---: | ----------- | | `legend_value` | boolean | `true` | v1.3.0 | Show/Hide the state in the legend. Will still display the name | | `as_duration` | string | | v1.3.0 | Will pretty print the states as durations. Doesn't affect the graph, only the tooltip/legend/header display. You provide the source unit of your sensor. Valid values are `millisecond`, `second`, `minute`, `hour`, `day`, `week`, `month`, `year`.
Eg: if the state is `345` and `as_duration` is set to `minute` then it would display `5h 45m` | -| `in_header` | boolean | `true` | v1.4.0 | If `show_states` is enabled, this would show/hide this specific serie in the header | +| `in_header` | boolean or string | `true` | v1.4.0 | If `show_states` is enabled, this would show/hide this specific serie in the header. If set to `raw` (introduced in NEXT_VERSION), it would display the latest raw state of the entity in the header bypassing any grouping/transformation done by the card. | | `in_chart` | boolean | `true` | v1.4.0 | If `false`, hides the serie from the chart | | `datalabels` | boolean or string | `false` | v1.5.0 | If `true` will show the value of each point for this serie directly in the chart. Don't use it if you have a lot of points displayed, it will be a mess. If you set it to `total` (introduced in NEXT_VERSION), it will display the stacked total value (only works when `stacked: true`) | | `hidden_by_default` | boolean | `false` | v1.6.0 | See [experimental](#hidden_by_default-experimental-feature) | diff --git a/src/apexcharts-card.ts b/src/apexcharts-card.ts index 2be52c2..c6fcafb 100644 --- a/src/apexcharts-card.ts +++ b/src/apexcharts-card.ts @@ -115,7 +115,7 @@ class ChartsCard extends LitElement { private _offset = 0; - @property({ attribute: false }) private _lastState: (number | string | null)[] = []; + @property({ attribute: false }) private _headerState: (number | string | null)[] = []; private _dataLoaded = false; @@ -191,6 +191,7 @@ class ChartsCard extends LitElement { }); let updated = false; + let rawHeaderStatesUpdated = false; this._config.series.forEach((serie, index) => { const entityState = (hass && hass.states[serie.entity]) || undefined; if (!entityState) { @@ -202,8 +203,18 @@ class ChartsCard extends LitElement { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this._graphs[index]!.hass = this._hass!; } + if (serie.show.in_header === 'raw') { + this._headerState[index] = this._computeLastState( + serie.attribute ? entityState.attributes[serie.attribute] : entityState.state, + index, + ); + rawHeaderStatesUpdated = true; + } } }); + if (rawHeaderStatesUpdated) { + this._headerState = [...this._headerState]; + } if (this._config.series.some((_, index) => this._entities[index] === undefined)) { this._warning = true; return; @@ -450,11 +461,11 @@ class ChartsCard extends LitElement { this._headerColors.length > 0 ? `color: ${this._headerColors[index]};` : ''}" - >${this._lastState?.[index] === 0 + >${this._headerState?.[index] === 0 ? 0 : (serie.show.as_duration - ? prettyPrintTime(this._lastState?.[index], serie.show.as_duration) - : this._lastState?.[index]) || NO_VALUE} ${!serie.show.as_duration ? html`${computeUom(index, this._config?.series, this._entities)}` @@ -505,11 +516,13 @@ class ChartsCard extends LitElement { graphData = { series: this._graphs.flatMap((graph, index) => { if (!graph) return []; - if (graph.history.length === 0) { - this._lastState[index] = null; - } else { - const lastState = graph.history[graph.history.length - 1][1]; - this._lastState[index] = this._computeLastState(lastState, index); + if (this._config?.series[index].show.in_header !== 'raw') { + if (graph.history.length === 0) { + this._headerState[index] = null; + } else { + const lastState = graph.history[graph.history.length - 1][1]; + this._headerState[index] = this._computeLastState(lastState, index); + } } if (!this._config?.series[index].show.in_chart) { return []; @@ -558,25 +571,25 @@ class ChartsCard extends LitElement { if (!graph) return []; let data = 0; if (graph.history.length === 0) { - this._lastState[index] = null; + if (this._config?.series[index].show.in_header !== 'raw') { + this._headerState[index] = null; + } data = 0; } else { const lastState = graph.history[graph.history.length - 1][1]; data = lastState === null ? 0 : lastState; - this._lastState[index] = this._computeLastState(lastState, index); + if (this._config?.series[index].show.in_header !== 'raw') { + this._headerState[index] = this._computeLastState(lastState, index); + } } if (!this._config?.series[index].show.in_chart) { return []; } - if (this._lastState[index] === null) { - return [0]; + if (this._config?.chart_type === 'radialBar') { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return [getPercentFromValue(data, this._config.series[index].min, this._config.series[index].max)]; } else { - if (this._config?.chart_type === 'radialBar') { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return [getPercentFromValue(data, this._config.series[index].min, this._config.series[index].max)]; - } else { - return [data]; - } + return [data]; } }), }; @@ -610,7 +623,7 @@ class ChartsCard extends LitElement { }; } // graphData.tooltip = { marker: { fillColors: ['#ff0000', '#00ff00'] } }; - this._lastState = [...this._lastState]; + this._headerState = [...this._headerState]; this._apexChart?.updateOptions( graphData, false, diff --git a/src/types-config-ti.ts b/src/types-config-ti.ts index af2354c..a0a360f 100644 --- a/src/types-config-ti.ts +++ b/src/types-config-ti.ts @@ -64,7 +64,7 @@ export const ChartCardAllSeriesExternalConfig = t.iface([], { "show": t.opt(t.iface([], { "as_duration": t.opt("ChartCardPrettyTime"), "legend_value": t.opt("boolean"), - "in_header": t.opt("boolean"), + "in_header": t.opt(t.union("boolean", t.lit('raw'))), "in_chart": t.opt("boolean"), "datalabels": t.opt(t.union("boolean", t.lit('total'))), "hidden_by_default": t.opt("boolean"), @@ -99,7 +99,7 @@ export const ChartCardSeriesExternalConfig = t.iface([], { "show": t.opt(t.iface([], { "as_duration": t.opt("ChartCardPrettyTime"), "legend_value": t.opt("boolean"), - "in_header": t.opt("boolean"), + "in_header": t.opt(t.union("boolean", t.lit('raw'))), "in_chart": t.opt("boolean"), "datalabels": t.opt(t.union("boolean", t.lit('total'))), "hidden_by_default": t.opt("boolean"), diff --git a/src/types-config.ts b/src/types-config.ts index d69a2ad..a1e5a04 100644 --- a/src/types-config.ts +++ b/src/types-config.ts @@ -61,7 +61,7 @@ export interface ChartCardAllSeriesExternalConfig { show?: { as_duration?: ChartCardPrettyTime; legend_value?: boolean; - in_header?: boolean; + in_header?: boolean | 'raw'; in_chart?: boolean; datalabels?: boolean | 'total'; hidden_by_default?: boolean; @@ -100,7 +100,7 @@ export interface ChartCardSeriesExternalConfig { show?: { as_duration?: ChartCardPrettyTime; legend_value?: boolean; - in_header?: boolean; + in_header?: boolean | 'raw'; in_chart?: boolean; datalabels?: boolean | 'total'; hidden_by_default?: boolean; diff --git a/src/types.ts b/src/types.ts index f0332e6..99481e4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,7 +26,7 @@ export interface ChartCardSeriesConfig extends ChartCardSeriesExternalConfig { show: { as_duration?: ChartCardPrettyTime; legend_value: boolean; - in_header: boolean; + in_header: boolean | 'raw'; in_chart: boolean; datalabels?: boolean | 'total'; hidden_by_default?: boolean;