I have set upper bound to 100 because I have put humidity on the Y-axis with my ON/OFF (0/100) sensor. Humidity is measured on a scale of 0-100%.
This allows me to have temperature on the X-axis which ranges from -5 to 40 degrees where I live. Not that I would see that full range in a day.
As you can see by comparing the two graphs between the posts.
I can now see the upward or downward trend of temperature with more detail. (Not just a straight bumpy line.)
At a glance where the humidity line sits on the graph gives me a rough approximation of percentage.
Plus the humidity line sits lower in the graph allowing the 0/100 sensor to be seen above at all times.
Humidity will never be 100%.
Before
After EDIT: Example shows what happens when not setting aggregate_func: max and ‘upper_bound_secondary: 100’
Different time spans in the above pictures. But was able to add a third temperature from the mezzanine of my living room without the graph looking messy.
Seriously, this case is supposed to be solved in a different way.
If the secondary-Y-axis value has a wide range, then playing with upper_bound may not help.
Consider a different approach:
Place 2 cards in a vert stack. Make them “overlap” by card-mod (find my examples here).
Using my method effectively frees up the Y-axis to be used by another reading, effectively giving a second Y-axis, pushing the binary_sensor to the back which only has two possible states.
It hurts my brain to make OFF/ON = 0/100 rather than the traditional 0/1 but at the end of the day we are applying a fudge to make the graph display what we want. Using 0/100 gives some range to the Y-axis to allow it to display something else quantitative.
Also dewpoint and temperature are very close together, this gives me the ability to see the relationship better.
There is a few use cases when comparing a percentage, with a numeric value and an ON/OFF state.
%CPU Use, CPU Temp, Fan ON/OFF state
%Humidity, Temperature, Humidifier ON/OFF state
%Humidity, CO2ppm, Door OPEN/CLOSED state
This method also makes all values on the grid available via mouse over. Plus less code.
Thanks for that link for display: grid, I will use the card mod to move my values where I want them.
FYI with a few days testing when using 0/100 aggregate_func: last has no affect. upper_bound_secondary: 100 and lower_bound_secondary: 0 is what is required.
It has many possible values & algorithm is complex, better to check a code. Just consider this simplest example:
Assume there are 60 readings (records in DB) within an hour; points_per_hour=6. Means - you do not need all 60 values for a graph, it will use only 6 values. Now how to convert each 10 real values into 1? Average, min, max, last? If you need only 6 values - then probably “average” is your choice. But if you have points_per_hour=60? 120? 240? These greater values are needed sometimes to show a “steplined” graph. In these cases an additional calculation to get “average” = not needed. Besides, for 0/1 graphs sometimes it shows 0 where it must be 1 - if you set aggregate_func wrongly.
With what you have noted above and me re-reading the docs have explained the behavior I am seeing in the below graphs. With some commentary.
Aggregate functions
Recorded values are grouped in time buckets which are determined by group_by, points_per_hour configuration. These buckets are converted later to single point/bar on the graph. Aggregate function defines the methods of that conversion.
Name
Since
Description
avg
v0.8.0
Average
median
v0.11.0
Median
min
v0.8.0
Minimum - lowest value
max
v0.8.0
Maximum - largest value
first
v0.9.0
last
v0.9.0
sum
v0.9.2
delta
v0.9.4
Calculates difference between max and min value
diff
v0.11.0
Calculates difference between first and last value
Name
Type
Default
Since
Description
group
boolean
false
v0.2.0
Disable paddings and box-shadow, useful when nesting the card. #Not to be confused for group_by
points_per_hour
number
0.5
v0.2.0
Specify amount of data points the graph should display for each hour, (basically the detail/accuracy/smoothing of the graph).
aggregate_func
string
avg
v0.8.0
Specify aggregate function used to calculate point/bar in the graph.
group_by
string
interval
v0.8.0
Specify type of grouping of data, dynamic interval, date or hour.
With 0/100- Setting no aggregate_function:for the entity.
The door open shows the short duration event at half the range.
(Must be some sort of default average?)
With 0/100- Settingaggregate_function: avgfor the entity.
The door open shows the short duration event at half the range.
Showing the average of readings in the time bucket.
With 0/100 - Settingaggregate_function: lastfor the entity.
The door open does not show the short duration event unless it is last in the time bucket.
With 0/100 - Settingaggregate_function:minfor the entity.
The door open only shows the minimum reading within each time bucket.
Short duration events won’t register unless there is a high point per hour count or short group_by time.
With 0/100 - Settingaggregate_function: maxfor the entity.
The door open only shows the maximum reading within each time bucket.
The door open uses the full range of graph, even for short duration events.
Hi all there,
I’m diabetic, and I would to share what I obtained after many hours of fiddling…
This is a graph from my CGM dexcom G6 linked to HA with dexcom integration.
I have achieved, with the help of some previous messages + an advice from ildar170975 to change dynamically the icon with the trend information of the dexcom integration, and to colorize the sate information accordingly to the value read. So visually i know immediately if all is OK or if something goes wrong !
I must just find a way for the 2 extreme trends states (rising-quickly and falling-quickly) to show a double arrow (up ⇈ or down ⇊ ) that indicates visually that the BG is changing very quickly and that I must make something about that… The double arrow is used on my pump and on the dexcom app, so it’s a known signal.
If someone has an idea to load an custom svg via card-mod, or show a second icon in that case…
I am using “binary_sensor → 0/1” template in many places - so just made a macro for it. Reusing a code drastically reduces a probability of error.
If this template is only used for template sensors - then a possible way could be using a blueprint for template sensor (it currently does not work for trigger-based sensors only).
Yeah, waiting eagerly for the template sensor blueprints to get fixed so I can use a template sensor - mines also in a macro - I hate writing stuff more than once - no need to maintain multiple lines of code
I use code similar to Ildar’s for my Son’s Dexcom, but with the UTF8 arrows (all of which have an HTML entity equivalent, same as you inserted into your post )