[Under New Management] Interactive history explorer custom card

Okay I just did a test on 2022.4 with my production database, rather than the test DB I have on my dev setup. It looks like this effect is much worse in 2022.4 than it was before the database changes. In fact, from some purely observational tests, it looks like the entire DB performance is worse in 2022.4.

That is not good news. It looks like they broke this even more in 2022.4 than it was before :frowning: I will have to do more testing. Ugh. Not the way I planned on spending my weekend…

Edit: yup, the database retrieval behavior changed in 2022.4. Now it won’t return the initial state at all anymore, as soon as it is outside of the requested range. The HA native history panel is also affected. It might be an artifact of database migration though, so I will wait a couple of days for new data to accumulate and then test again. If this persists, it’s a bug that will have to be reported for the recorder component.

Yes, it’s definitely worse than before, but it’s usable. Hopefully, you’ll get some attention from the development team.

Thanks for the update.

Just got this card added tonight and am absolutely loving it.

.

I want to create a history graph that shows when my AC is running. That is stored in an attribute, not the state. The entity’s state is what mode it is in, so it just shows ‘auto’ all the time (unless I flip to either ‘heat’ or ‘cool’ or ‘off’). Whether the system is running or not is stored in an ‘hvac_action’ attribute that is either ‘idle’, ‘heating’, or ‘cooling’. I know the attribute I’m after is getting recorded because I can see when the system is running in the stock built-in history graph (though, the ui for that graph is bit ugly).

I suspect the answer is to create a sensor template that sets its state based on the actual entity’s attribute, but thought I would ask if anyone had any better ideas before I did that.

Is there a cleaner way to get history graph of an attribute?

The problem fixed itself with new data being stored in the db using the new table format introduced in 2022.4. It only affected the part of your data that was previously migrated from the old to the new format. Looks like a bug in the migration process, but no big deal as this migrated data will be pushed out progressively as new data comes in.

Yeah pretty much. Just a simple template sensor will do. Adding native support for attributes to the card would very significantly impact the overall performance of the card, even on entities that don’t use attributes. The changes in 2022.4 made this even more clear cut, as there is now an official setting in the API to ignore all attributes for better performance (there already was such a setting previously, but the loss of attributes was merely a sideeffect back then ; now it’s official).

1 Like

Sneak preview for the next version, wind direction time lines !

2 Likes

I figured as much. I was worried about the efficiency of storing the data in the recorder twice, but hadn’t considered the efficiency of having to do the math to display an attribute. Disk space is cheap. I can live with this.

So my life can serve as a warning to others, here is what I did:

The goal was to create that Ecobee-esque history like arasboo posted above so I could track how my HVAC was performing. I miss my Ecobee. My new system didn’t like them, so I’m having to use their thermostats instead. New system is a mini-split, so there is one outdoor thing shared by four indoor things, so everything below repeats four times.

My HVAC’s climate entity has a huge list of attributes that looks kinda like this, with a bunch of lines trimmed to focus on the important bits. The ‘hvac_mode’ is what I set it to and becomes the entity’s state. The ‘hvac_action’ is what the equipment is actually doing. And those ‘current_*’ and ‘target_*’ attributes are useful to keep an eye on.

hvac_modes:
  - auto
  - heat
  - cool
  - 'off'
fan_modes:
  - auto
  - 'on'
  - low
  - medium
  - high
  - Schedule
preset_modes:
  - Schedule
  - Temp Hold
  - Away
  - Manual
current_temperature: 67
target_temp_high: 75
target_temp_low: 67
current_humidity: 41
fan_mode: auto
hvac_action: heating
preset_mode: Schedule
aux_heat: 'off'
fan: 'on'
schedule_mode: true
friendly_name: Den

The attribute becomes a sensor with a template like this, times four.

sensor:
  - platform: template
    sensors:
      hvac_den:
        friendly_name: "Den"
        value_template: "{{ state_attr('climate.den', 'hvac_action') }}"

Then I created a card like this.

type: custom:history-explorer-card
header: HVAC History
defaultTimeRange: 3d
recordedEntitiesOnly: true
uimode: dark
uiLayout:
  selector: hide
uiColors:
  labels: white
  buttons: rgba(0,0,0,0)
showTooltipColorsLine: false
showTooltipColorsTimeline: false
stateColors:
  sensor.idle: grey
  sensor.cooling: dodgerblue
  sensor.heating: red
graphs:
  - type: timeline
    entities:
      - entity: climate.den
        name: System
      - entity: sensor.hvac_den
      - entity: sensor.hvac_bedroom
      - entity: sensor.hvac_living_room
        name: Living Rm
      - entity: sensor.hvac_upstairs
  - type: line
    title: Temperature
    entities:
      - entity: sensor.den_indoor_temperature
        color: yellow
        fill: rgba(0,0,0,0)
        name: Den
      - entity: sensor.bedroom_indoor_temperature
        color: green
        fill: rgba(0,0,0,0)
        name: Bedroom
      - entity: sensor.living_room_indoor_temperature
        color: dodgerblue
        fill: rgba(0,0,0,0)
        name: Living Room
      - entity: sensor.upstairs_indoor_temperature
        color: orange
        fill: rgba(0,0,0,0)
        name: Upstairs
      - entity: sensor.den_outdoor_temperature
        color: red
        fill: rgba(0,0,0,0)
        name: Outside

The end result was a graph that looked like this, where I can see what mode the system is set to and when each unit turns on and off.

This is nearly exactly the view I wanted before you created this card. This is awesome. Now, the next step is to change the crap insulation in my house so the system doesn’t run so often. There’s way too much red on that graph.

1 Like

I have two geothermal systems and ecobee thermostats. I’m stealing this.

Version 1.0.21 is out !

New features include compass arrow graphs to visualize wind direction, bearing and everything directional:
image

Adjustable tooltip sizes:

Removable time tick labels for more optimized use of vertical space and the Ctrl-mouse wheel now zooms to the current cursor position.

3 Likes

Wow, Alex. This all is more than great. Zoom over mouse, tooltip sizes, etc. etc.

Only one questions regarding your doc:

Configuring the tooltip popup
The tooltip popups used in timelines and arrowlines support three different sizes and layout modes: full, compact and slim. By default, the mode is selected automatically depending on the available space around the graph. The mode can be overidden manually too:

type: custom:history-explorer-card
tooltipSize: slim       # Supported modes are full, compact, slim or auto

Is auto a size as well? Because in the description you are currently distinguishing between a size an a mode. And that a size can be set and a mode can be overwritten. Is the mode the same as the size?

And is it possible to set - instead of – in compact and slim mode? Or do I have to change generateTooltipContents on my own?

Size = mode in this context, I was in a hurry when I wrote the docs :slight_smile: If you set it to auto (which is the default) then it will use full size when there’s (vertical) space to do it, otherwise it will use compact size. Edit: I made this section of the readme a little less confusing.

Full and compact basically contain the same data, just layed out differently. Full is nice when you are looking specifically at the lengths of events in your history, since the start and end times are aligned. It’s faster to mentally parse than the single line time and date of compact and slim sizes. If you don’t need the info, you can just globally use compact or slim. Note that this will only affect timeline and arrowline graphs. The tooltips for line graphs are different and unaffected by this setting.

I will probably add some more tooltip customization options in the future.

2 Likes

OK…This has been bugging me all day. How do you decimate an arrow? Is it a scalar or a vector?

It’s a scalar, it represents an angle (direction or bearing). The arrow graph actually works differently from other graphs: instead of scrolling with the graphs when you slide, the arrows stay at fixed positions on screen and it’s the data that scrolls beneath them. So when you scroll past, the arrows will animate and show the fluctuations of the data as you glide over it. So the real decimation is implicit because there’s always a fixed number of arrows. But the data beneath it is never decimated and its trends and fluctuations become visible with the animation of the arrows.

This is an example that show fluctuations in wind directions as you scroll through the graph:
output

Thanks for the explanation. I was wondering how the data are presented when scales are changed. So it’s as simple as breaking the scales into the resolution of the number of arrows that fit, and then figuring the value at that time. There’s no averaging or decimation involved, just resampling.

This is what I see after accumulating some data since yesterday:

Edit: I might’ve been presumptuous. Is the above correct?

To be honest it is missing initial state in both your card and in the default history panel whenever I reboot. Until it accumulates enough history to fill the panel. It also shows entities that have been deleted until such time as I reboot. I’m hoping the core team look into it, it seems a bit ‘average’ at the moment.

When I get some time I’ll look into it, but fixing things that are going to break in 2022.5 at the moment.

Correct. Averaging angles is tricky. Say you had 1 day of northerly followed by 1 day of southerly. The average would be east (or west, depending how the angular interpolation is done), which is completely wrong. You would have to use averaged clustering or similar (like 90% of the time the wind was approximately north), but that makes things quite complex and slow and has a tendency to fail in edge cases (doesn’t mean I won’t add something like this later on though). So using nearest resampling will guarantee a valid measure to be shown. And scrolling through will show how stable the measure is.

Yeah I noticed the same. Looks like a regression in the recorder component since the 2022.4 release.

Does not play well with auto-entities.

Is there a way to do filters and excludes to dynamically set which entities appear in a graph?

I don’t understand the question. Can you explain what exactly the problem is ?

Auto-entities is a plugin that auto populates the entities: section of a card based on filters. It allows for dynamically-populated cards. As an example, I have an Entities card that is a list of all the lights that are on. When a light gets turned off, it disappears off the card.

On a page where I track energy usage, I have a History card that shows the timeline for each device that my Sense power monitor detects. Since the Sense will randomly detect new devices, this is not a hard-coded list of devices but instead a dynamically populated list. It looks like this:

  - type: custom:auto-entities
    show_empty: false
    sort:
      method: name
    card:
      show_header_toggle: false
      state:
        - color: red
          value: 'on'
        - color: grey
          value: 'off'
      title: Sense Detected Devices
      type: history-graph
    filter:
      include:
        - attributes:
            device_class: power

I would love to convert this to a history-explorer-card, since it is better than a history-graph in a couple dozen different ways. ((Thank you, again. I am really loving this card.))

When I try to use auto-entities with a history-explorer-graph card, like this (in a stripped-down simplified example):

  - type: custom:auto-entities
    card:
      type: custom:history-explorer-card
      graphs:
        - type: timeline
    filter:
      include:
        - entity_id: sun.sun

I get this:

(!) undefined is not an object (evaluating 'i.graphs[e].entities')
entities:
  - entity: sun.sun
type: custom:history-explorer-card
graphs:
  - type: timeline

Auto-entities is creating the card with the populated entities: section, but it creates it at the card level whereas this specific card really needs the entities: to be under graphs: > type:.

To be honest, this sounds more like a limitation of the auto entities integration, which I guess should be a bit more configurable on where/how it generates its entities. The problem is that you can’t just dump a list of entities into the history explorer card, as it supports multiple type of graphs and the type cannot always be automatically deduced from just the entity_id.

Can’t you somehow configure the auto entity thing to change the hierarchical indentation level of its generated YAML ? Instead of just dumping everything at root level.

Most other cards populate their entities: at the card level rather than under another tag, so this works 98% of the time.

What makes your card different is doing multiple graphs with different entity lists in a single card. If the entities: was at card level and the graph_type: was set for the desired output, we would only get one graph per card and would then repeat that for multiple cards to get the multiple graphs. This would break the linkage between the multiple graphs, which is counter what makes this awesome. So, that’s a nonstarter.

The other solution is to liberally plagiarize the filter.ts file from the auto-entities source code and implement filters within this card. This would be a less-than-trivial amount of work, so it would take some thought and effort to even decide if it was worth it.

I’ll fork your GitHub thing and take a swing at it. If I get it working, I’ll submit it back to you. My free time is near zero lately, so it may take me a while.