kalkih / mini-graph-card

Minimalistic graph card for Home Assistant Lovelace UI
MIT License
2.96k stars 232 forks source link

Extrema does not work with aggregated chart #911

Open airmaxx opened 1 year ago

airmaxx commented 1 year ago

I'm showing a bar chart of my energy consumption in the last seven days. While the bars work correctly thanks to aggregate_func, the Min extrama is always 0

 hours_to_show: 168
 aggregate_func: max
 group_by: date
 show:
   graph: bar
   extrema: true
parautenbach commented 1 year ago

Very old issue... Unlikely to be fixed, it seems, but I have a similar example. It looks like the min/max on the chart doesn't take the min/max of the aggregated values, but instead of the raw values. In my case, my sensor is a daily cumulative value that always starts at 0, so the value for min is then 0 too, even though the value for the day is non-zero. It doesn't matter which aggregate function I choose. It's always 0.

      - type: custom:mini-graph-card
        entities:
          - sensor.daily_solar_energy_consumption
        lower_bound: 0
        hours_to_show: 168
        aggregate_func: last
        group_by: date
        show:
          graph: bar
          state: true
          extrema: true
Kokicha commented 1 year ago

I've exactly the same problem, also with an energy bar graph. "Unlikely to be fixed" - why not?

ildar170975 commented 1 year ago

"Unlikely to be fixed" - why not?

Due to a lack of developers maintaining the project. Current priority is mainly rectifying critical bugs...

ildar170975 commented 1 year ago

aggregated values

Pieter, could you elaborate what do you mean by this?

Consider this card for a sensor with scan_interval=60:

hours_to_show: 6
points_per_hour: 60
group_by: interval

Here you will see a curve which is close to a real curve (it will be even closer if you set points_per_hour: 120; otherwise you MAY miss some changes). Extrema values will be also "close" to real ones.

Surely if you set points_per_hour: 5 you will get a not-precise curve and possibly wrong extremas.

Then, if you set group_by: hour if will automatically set points_per_hour: 1 -> and you know all the rest.

parautenbach commented 1 year ago

What I mean is that if I group by day then I expect the min and max to be the values from aggregated values and not taken from the raw values.

Example: Day 1 at time x: 1 Day 1 at time y: 2 Day 2 at time x: 3 Day 2 at time y: 2

Grouped by day using sum: Day 1: 3 Day 2: 5

Min must be 3, max must be 5 and not 1 and 3 respectively. I see this issue specifically for min and not max.

ildar170975 commented 1 year ago
  1. I was wrong here:

    Surely if you set points_per_hour: 5 you will get a not-precise curve and possibly wrong extremas.

Just rechecked it - extrema values will be from "raw" data. Means: extrema shows SAME data:

type: vertical-stack
cards:
  - type: custom:mini-graph-card
    entities:
      - sensor.xiaomi_cg_1_co2
    hours_to_show: 4
    points_per_hour: 1
    show:
      extrema: true

  - type: custom:mini-graph-card
    entities:
      - sensor.xiaomi_cg_1_co2
    hours_to_show: 4
    points_per_hour: 12
    show:
      extrema: true

  - type: custom:mini-graph-card
    entities:
      - sensor.xiaomi_cg_1_co2
    hours_to_show: 4
    points_per_hour: 120
    show:
      extrema: true

  - type: custom:mini-graph-card
    entities:
      - sensor.xiaomi_cg_1_co2
    hours_to_show: 4
    points_per_hour: 120
    group_by: hour
    show:
      extrema: true

изображение

Grouped by day using sum: Day 1: 3 Day 2: 5

Why do you expect a SUM? You have aggregate_func: last. group_by - according to the code (may be I missed smth) - affects on points_per_hour & a right time border of a graph.

parautenbach commented 1 year ago

Thanks for confirming, Ildar!

Oh, it's just one of my charts exhibiting this issue. I happen to have copied one with last.

I just chose sum for my example, but it could've been last too.

ildar170975 commented 1 year ago
  1. So, you need to check with aggregate_func: sum and see if extrema is defined properly. Cannot do it myself, I have no real sensors for which I may use SUM... Probably could do it with some test sensors...

  2. Could you tell me a purpose of this aggregate_func: sum ? Frankly speaking, I never understood it... What is a real-life scenario?

parautenbach commented 1 year ago

I'm not sure what you mean here exactly, but to me, it looks like it doesn't really matter what the aggregate function is. If I have 3 summed values (that are all different), the min should be the smallest summed value and not the smallest raw value.

My examples here use the built-in statistics card, because of this issue (so I don't have the extrema here).

This is e.g. the sum of counts of when a specific motion sensor was triggered. The min should be the total (sum) for the day with the smallest count.

Screenshot 2023-06-12 at 14 18 44

The source sensor looks like this. It's a count that resets every day and has state_class: total_increasing in configuration.yaml:

- platform: history_stats
  name: Foyer Motion Detections
  entity_id: binary_sensor.foyer_motion_detected
  state: "on"
  type: count
  start: "{{ now().replace(hour=0, minute=0, second=0) }}"
  end: "{{ now() }}"

One could say I'm plotting daily values when I already have daily values, but that would be missing the point: If I wanted to plot the daily values by aggregating it per week or month, you need to use the sum function and then the extrema will be wrong.

Same here for the total amount of hours the Apple TV has been playing:

Screenshot 2023-06-12 at 14 19 13

For an example using last:

This is the total amount of PV (solar) used (consumed) per day.

Screenshot 2023-06-12 at 14 19 33

It's sensor looks like this, so it's a value that resets at midnight, similar to the ones above, but using another mechanism (a utility meter). Using a sum here wouldn't make sense: You want to use the last value for a given day. I would expect min to be the day with the lowest last value, but instead it's zero, since all days has a zero value when it resets.

utility_meter:
  daily_solar_energy_consumption:
    source: sensor.pv_energy
    cycle: daily