Skip to content

Conversation

dbuezas
Copy link
Owner

@dbuezas dbuezas commented Nov 4, 2022

No description provided.

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 4, 2022

@zanna-37, now that you have separated all unrelated fixes, I rebased my offsets branch.

If you have time to close the duplicated datapoints issue, please PR to this branch :). Otherwise, I hope to it sooner or later

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 4, 2022

  • I hope i can get on it sooner or later

@dbuezas dbuezas force-pushed the feat/time-offsets branch 2 times, most recently from 30c1b72 to 7f695c2 Compare November 6, 2022 22:39
@dbuezas
Copy link
Owner Author

dbuezas commented Nov 6, 2022

@zanna-37 I rebased now, which includes the better management of the "fake datapoints" and (inspired by you) reworked the git history into "do all the code" and "add a line to the readme" 😁
With that, I think it is almost done 🎉

I think the only thing missing for the offsets is to rework the removeOutsideRange function in the cache.ts file, so it accounts for the offsets. It should work fine now, but it handles the cache very inefficiently (it will delete stuff just to refetch it again an instant later).

Another option is to be less strict removing stuff from the cache. Originally this functionality was there only to ensure that plotly autorange would put in the screen the right xaxis range to respect hours_to_show. Now that's not necessary anymore.

if (xs.length === 0) return;
const last = JSON.parse(JSON.stringify(ys[ys.length - 1]));
xs.push(new Date());
xs.push(new Date(Date.now() + offset));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extendLastDatapointToPresent(...) should be disabled when an offset is set. Those traces reflects values that are not related to the present.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this.
An extreme case is a monthly statistic, without extending, it will look like the plot just stops at end of last month.
IMO, of the behavior is to extend to the present, then it should be consistent or it will surprise the user.
I'll put some example screenshots later

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it depends. 😂
When using offsets, we are talking about things that occurred in the past and is now being shifted.
If we talk about forecast it doesn't make sense to extend, because the forecast is referred to a specific point in time, extending it is nonsensical.
However, when talking a tank level, if the level stays at X liters, and it doesn't change, it would make sense to extend it.

Neither is perfect, but maybe the second scenario is more common so we should stick with your vision. Opinions?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. Give it a try when you test it. I think when you see how a part of the plot disappears as soon as the offset is added you may get the same "this is wrong" feeling.

It is true that it can be seen as a (poor) forecast, but it can also be interpreted as "the last known state at that point".

Let me know what you find out from experimenting. We can always add an option to deactivate the extension

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For temperatures and statistics (which are currently timed at the start of their period) extending is surprising, because it extends horizontally between one and two hours but the real temperature didn't stay constant. It looks wierd. If you extended by adding the current state instead of the last fetched one it would look better, but that's IMHO too smart, non generalizable and out of scope.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "extendLastDatapointToPresent" is not a problem if the offset is moving the trace later.

If one offsets right (positive) by a month and the visible range is a week, the only the section [now - 1month -1 week, now - 1month] will he fetched] . Extending that to now will just add a huge 1 month straight line (visible when you zoom).
If one offsets left (negative), then it is less problematic

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if having data past now is not a problem

X axis scaling is now done explicitly, so this is less of an issue now

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that my proposition makes having an offset (say a small enough offset that you cannot see, but non-zero nonetheless) totally transparent and not changing suddenly the way the trace looks.

I think i got you now. Whatever we do, it should be equivalent to expanding the true last state first and the offseting. (Not offsetting and then expanding the last fetched one, which may not be the latest state of the sensor)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i got you now. Whatever we do, it should be equivalent to expanding the true last state first and the offseting.

If there is an existing state right of the visible range, it should probably be fetched for continuity purposes. Extending the last visible state to the right only works when plotting the values piecewise constant. With other interpolation methods the result is wrong.

If there is no such later state, you may want to assume the state did not change by extending to the right, but never past now+offset. I believe this should default to true for normal history and false for statistics, but should be configurable by the user.

Sadly, I don't think HA has a suitable API to fetch « whatever is the next point after this time » so the first paragraph may be infeasible at least for sensors updating very irregularly.

Copy link
Owner Author

@dbuezas dbuezas Nov 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never past now+offset

absolutly


I believe this should default to true for normal history

Agree


and false for statistics

It took me a second to realise why, but I agree now too


but should be configurable by the user.

Also agree. Luckily very easy to implement with the new better structured code.


I don't think HA has a suitable API to fetch « whatever is the next point after this time »

Yeah, I didn't find such an API either.


I'll give this a try now and finally merge this PR

Copy link
Contributor

@zanna-37 zanna-37 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 7, 2022

Offset should be considered on src/plotly-graph-card.ts, rows 171-176.

https://github.com/dbuezas/lovelace-plotly-graph-card/pull/109/files#diff-c0352c6cdab9f9d6e1251e51657ccfc84873e2c7b361622d9aa4094c04c11093R171-R176

The cache doesn't store an offset history. The offset is applied in the getter in cache.ts/getHistory(Entity)

Meaning, it shouldn't be necessary to consider when adding it from the present in refres_interval: auto

@dbuezas dbuezas force-pushed the feat/time-offsets branch 2 times, most recently from dd97508 to 160c7f2 Compare November 12, 2022 19:49
@dbuezas
Copy link
Owner Author

dbuezas commented Nov 12, 2022

Config for extending works.

image

type: custom:plotly-graph-dev
entities:
  - entity: sensor.electricity_total
    extend_to_present: false
    line:
      width: 10
  - entity: sensor.electricity_total
    extend_to_present: true 
hours_to_show: 0.03
update_interval: 1

I think this PR can be merged.
@zanna-37 Should I merge or wait? If you still intend to review the readme of offsets let me know! :)

@zanna-37
Copy link
Contributor

Yes, I'll write the README for offset, maybe tomorrow morning.

Regarding the last code changes, ff you want to wait I can give a look at the code.

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

Yes, I'll write the README for offset, maybe tomorrow morning.

Thanks :) !!!

Regarding the last code changes, ff you want to wait I can give a look at the code.

Will be very appreciated! I removed the cache clearing code (*), but had to still add it before plotting to ensure the yaxis auto range applies to the visible section. (So if you reset, the data won't be deleted from cache, but will still not be plotted)

(*) It's kind of hard when combined with offsets, as the same entity may be shown with different offsets in the same plot.

@zanna-37
Copy link
Contributor

It's kind of hard when combined with offsets, as the same entity may be shown with different offsets in the same plot.

It's difficult for me to review the code since I'm losing track of what methods works on the actual values of the offsetted ones.

By the way, it might be a good idea to use entityname+offset as the cache key.

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

it might be a good idea to use entityname+offset

The idea is to not fetch the same values twice. The entity key determines the raw data (more or less), and the offsets are applied only before plotting. Multiple traces can be derived from the same cached entry (each with different offsets, lambdas, etc). That's why the cache key only holds the entity name, attribute and statistic type and period.

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

what methods works on the actual values of (or?) the offsetted ones.

The offset is only applied to decide what to fetch, and then right before plotting. I think i may remove the offset logic from the cache to make that more evident

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

In any case, I'm fairly confident about the offset logic, so the readme would be the most valuable contribution :)

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

But you can point out at something specific that is confusing, I'll gladly try to improve it :)

@zanna-37
Copy link
Contributor

Either we keep the cache as points that will be plotted (offset already applied) and in this case we keep separate traces for the same entity with different offset.
OR
We keep the raw entity in the cache but we must be careful about merging and deleting the out-of-range.

so the readme would be the most valuable contribution

I know, it's coming.

point out at something specific

it's just documentation, for methods and vars, but don't worry, I know it's a burden and the problem is mine, not yours 😂

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

OR
We keep the raw entity in the cache but we must be careful about merging and deleting the out-of-range.

100%. That's the approach i took in the PR. To solve the deleting problem, i just stopped deleting the cache, but filter the "post processed" data before giving it to plotlyjs.

I just saw that there is a bug (plotlyjs again), where the autorrange button (or double clicking) autorranges to the widest past scales instead of the visible data. It is probably storing that as a side effect somewhere, instead of traversing the data again. I'll try to work around that next.

@zanna-37
Copy link
Contributor

I just stopped deleting the cache

So when the graph stays there for too long we are filling the memory indefinitely. Right?

@dbuezas
Copy link
Owner Author

dbuezas commented Nov 13, 2022

I just stopped deleting the cache

So when the graph stays there for too long we are filling the memory indefinitely. Right?

Yes, that's the caveat. And slower operations (filtering happens linearly, no binary search for the boundaries or anything of the sort.
I don't think it should be too tragic though. Worse case we could clear the cache every hour.
Maybe i refactor the cache eventually and implement it better. At the moment, the same info will ve fetched more than once if you plot multiple attributes of the same entity

@dbuezas dbuezas marked this pull request as draft November 13, 2022 16:06
- entity: sensor.actual_temperature
```

### Extend_to_present
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FrnchFrgg
Here's the toggle for extend_to_present with the defaults you suggested

Clearing out-of-view data was used to ensure xaxis autoranging would show the expected time range in the screen, but xaxis autoranging is not used anymore, and this technique is incompatible with offsets.
This makes auto ranging after resetting behave as it used to (only show as much as zoomed out since the last reset)
type: custom:plotly-graph
entities:
- entity: sensor.weather_24h_forecast
mode: "markers"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: is mode documented somewhere?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not within this repo's readme, it's a plotlyjs feature, so it's in their docs

@zanna-37
Copy link
Contributor

README ready at #142.

@dbuezas dbuezas marked this pull request as ready for review November 15, 2022 19:47
@dbuezas dbuezas merged commit be039f3 into master Nov 15, 2022
@dbuezas dbuezas changed the title Feat/time offsets (WIP) Feat/time offsets Nov 15, 2022
@dbuezas dbuezas mentioned this pull request Nov 15, 2022
@dbuezas dbuezas deleted the feat/time-offsets branch November 15, 2022 21:10
@dbuezas
Copy link
Owner Author

dbuezas commented Jan 28, 2023

@zanna-37 fyi: in v3, the offsets are called time_offset. I had to rename the property to avoid a collision with a plotlyjs config to offset bar charts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants