Skip to content

Commit

Permalink
feat(series.offset): Compare data from another timeframe with the cur…
Browse files Browse the repository at this point in the history
…rent timeframe (RomRider#19)

Fixes RomRider#18
  • Loading branch information
RomRider authored Jan 29, 2021
1 parent 0835077 commit af8ba81
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 10 deletions.
22 changes: 22 additions & 0 deletions .devcontainer/ui-lovelace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ views:
- entity: sensor.random_0_1000
name: Sensor 2
type: area
offset: -1d
graph_span: 15min
cache: true
layout: minimal
Expand All @@ -33,6 +34,8 @@ views:

- type: custom:apexcharts-card
stacked: true
span:
offset: -1d
series:
- entity: sensor.random_0_1000
name: RAM Usage
Expand Down Expand Up @@ -228,3 +231,22 @@ views:
const value = entity.attributes[attr];
return [moment().startOf('day').hours(hour).valueOf(), value];
})
- type: custom:apexcharts-card
graph_span: 8d
span:
start: hour
# apex_config:
# dataLabels:
# enabled: true
header:
show: true
title: Precipitation Forecast
series:
- entity: weather.openweathermap
type: area
extend_to_end: false
data_generator: |
return entity.attributes.forecast.map((entry) => {
return [new Date(entry.datetime), entry.temperature];
});
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ However, some things might be broken :grin:
- [Simple graph](#simple-graph)
- [Multiple Types of Graphs](#multiple-types-of-graphs)
- [Aggregating data](#aggregating-data)
- [Compare data from today with yesterday](#compare-data-from-today-with-yesterday)

## Installation

Expand Down Expand Up @@ -121,6 +122,7 @@ The card stricly validates all the options available (but not for the `apex_conf
| `group_by` | object | | v1.0.0 | See [group_by](#group_by-options) |
| `invert` | boolean | `false` | v1.2.0 | Negates the data (`1` -> `-1`). Usefull to display opposites values like network in (standard)/out (inverted) |
| `data_generator` | string | | v1.2.0 | See [data_generator](#data_generator-option) |
| `offset` | string | | NEXT_VERSION | This is different from the main `offset` parameter. This is at the series level. It is only usefull if you want to display data from for eg. yesterday on top of the data from today for the same sensor and compare the data. The time displayed in the tooltip will be wrong as will the x axis information. Valid values are any negative time string, eg: `-1h`, `-12min`, `-1d`, `-1h25`, `-10sec`, ... |


### `show` Options
Expand Down Expand Up @@ -416,3 +418,20 @@ series:
duration: 10min
func: first
```

### Compare data from today with yesterday

```yaml
type: custom:apexcharts-card
graph_span: 1d
span:
start: day
header:
show: false
series:
# data from today
- entity: sensor.temperature
# data from yesterday offsetted to be displayed today
- entity: sensor.temperature
offset: -1d
```
8 changes: 8 additions & 0 deletions src/apexcharts-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class ChartsCard extends LitElement {

private _dataLoaded = false;

private _seriesOffset: number[] = [];

public connectedCallback() {
super.connectedCallback();
if (this._config && this._hass && !this._loaded) {
Expand Down Expand Up @@ -194,6 +196,11 @@ class ChartsCard extends LitElement {
if (config.span?.end && config.span?.start) {
throw new Error(`span: Only one of 'start' or 'end' is allowed.`);
}
config.series.forEach((serie, index) => {
if (serie.offset) {
this._seriesOffset[index] = validateOffset(serie.offset, `series[${index}].offset`);
}
});

this._config = mergeDeep(
{
Expand Down Expand Up @@ -231,6 +238,7 @@ class ChartsCard extends LitElement {
this._config!.cache,
serie,
this._config?.span,
this._seriesOffset[index] || 0,
);
}
return undefined;
Expand Down
31 changes: 26 additions & 5 deletions src/graphEntry.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HomeAssistant } from 'custom-card-helpers';
import { ChartCardSeriesConfig, EntityCachePoints, EntityEntryCache, HassHistory, HistoryBuckets } from './types';
import { compress, decompress, log } from './utils';
import localForage from 'localforage';
import localForage, { config } from 'localforage';
import { HassEntity } from 'home-assistant-js-websocket';
import { DateRange } from 'moment-range';
import { HOUR_24, moment } from './const';
Expand Down Expand Up @@ -47,12 +47,15 @@ export default class GraphEntry {

private _md5Config: string;

private _offset = 0;

constructor(
index: number,
graphSpan: number,
cache: boolean,
config: ChartCardSeriesConfig,
span: ChartCardSpanExtConfig | undefined,
offset = 0,
) {
const aggregateFuncMap = {
avg: this._average,
Expand All @@ -70,6 +73,7 @@ export default class GraphEntry {
this._history = undefined;
this._graphSpan = graphSpan;
this._config = config;
this._offset = offset;
const now = new Date();
const now2 = new Date(now);
this._func = aggregateFuncMap[config.group_by.func];
Expand All @@ -89,7 +93,7 @@ export default class GraphEntry {
}

get history(): EntityCachePoints {
return this._computedHistory || this._history?.data || [];
return this._offsetData(this._computedHistory || this._history?.data || []);
}

get index(): number {
Expand All @@ -104,6 +108,17 @@ export default class GraphEntry {
return this._realEnd;
}

private _offsetData(data: EntityCachePoints) {
if (this._offset) {
const lData = JSON.parse(JSON.stringify(data));
lData.forEach((entry) => {
entry[0] = entry[0] - this._offset;
});
return lData;
}
return data;
}

private async _getCache(key: string, compressed: boolean): Promise<EntityEntryCache | undefined> {
const data: EntityEntryCache | undefined | null = await localForage.getItem(
`${key}_${this._md5Config}${compressed ? '' : '-raw'}`,
Expand Down Expand Up @@ -136,8 +151,14 @@ export default class GraphEntry {
if (this._config.data_generator) {
this._history = this._generateData(start, end);
} else {
this._realStart = start;
this._realEnd = end;
this._realStart = new Date(start);
this._realEnd = new Date(end);
const endHistory = new Date(end);

if (this._offset) {
startHistory.setTime(startHistory.getTime() + this._offset);
endHistory.setTime(endHistory.getTime() + this._offset);
}

let skipInitialState = false;

Expand Down Expand Up @@ -165,7 +186,7 @@ export default class GraphEntry {
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
new Date(history.data.slice(-1)[0]![0] + 1)
: startHistory,
end,
endHistory,
skipInitialState,
);
if (newHistory && newHistory[0] && newHistory[0].length > 0) {
Expand Down
1 change: 1 addition & 0 deletions src/types-config-ti.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const ChartCardSeriesExternalConfig = t.iface([], {
"invert": t.opt("boolean"),
"data_generator": t.opt("string"),
"float_precision": t.opt("number"),
"offset": t.opt("string"),
"group_by": t.opt(t.iface([], {
"duration": t.opt("string"),
"func": t.opt("GroupByFunc"),
Expand Down
1 change: 1 addition & 0 deletions src/types-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface ChartCardSeriesExternalConfig {
invert?: boolean;
data_generator?: string;
float_precision?: number;
offset?: string;
group_by?: {
duration?: string;
func?: GroupByFunc;
Expand Down
10 changes: 5 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,17 @@ export function computeName(
entity: HassEntity | undefined = undefined,
): string {
if (!config || (!entities && !entity)) return '';
let name = '';
if (entity) {
return config.series[index].name || entity.attributes?.friendly_name || entity.entity_id || '';
name = config.series[index].name || entity.attributes?.friendly_name || entity.entity_id || '';
} else if (entities) {
return (
name =
config.series[index].name ||
entities[index]?.attributes?.friendly_name ||
entities[entities[index]]?.entity_id ||
''
);
'';
}
return '';
return name + (config.series[index].offset ? ` (${config.series[index].offset})` : '');
}

export function computeUom(
Expand Down

0 comments on commit af8ba81

Please sign in to comment.