custom-cards / flex-table-card

Highly Flexible Lovelace Card - arbitrary contents/columns/rows, regex matched, perfect to show appdaemon created content and anything breaking out of the entity_id + attributes concept
GNU General Public License v3.0
198 stars 23 forks source link

Howto sort on sensor attributes #7

Closed riker09 closed 5 years ago

riker09 commented 5 years ago

First of all thank you for this great custom card. I think it is really useful and has a lot of potential. Not all data fits into a colorful bar/pie/line chart, some things make perfect sense in a table. :slightly_smiling_face:

Now, as discussed in issue #4 flex-table-card supports the attributes of a sensor. I query an API that gives me gas prices of some nearby gas stations (diesel + e5). The sensor name is sensor.gas_prices and the attribute name is stations and the payload I read with Jinja template {{ state_attr("sensor.gas_prices","stations") }} looks like this:

[
    {
        "id": "dadfc9a7-3715-453c-af05-d1dc6354843e",
        "name": "Name of station A",
        "brand": "TOTAL",
        "street": "Street name a",
        "place": "City name",
        "lat": 50.123456,
        "lng": 10.123456,
        "dist": 2,
        "diesel": 1.279,
        "e5": 1.359,
        "e10": 1.339,
        "isOpen": true,
        "houseNumber": "3",
        "postCode": 12345
    },
    {
        "id": "ed7869ad-8d7c-4ee6-86fa-6c1d03d5e047",
        "name": "Name of station B",
        "brand": "Shell",
        "street": "Street name b",
        "place": "City name",
        "lat": 50.654321,
        "lng": 10.654321,
        "dist": 3.2,
        "diesel": 1.269,
        "e5": 1.359,
        "e10": 1.319,
        "isOpen": true,
        "houseNumber": "",
        "postCode": 12354
    }
]

And sure enough I can display the values in a table with this YAML config:

type: 'custom:flex-table-card'
title: Gas prices
max_rows: 10
entities:
  include: sensor.gas_prices
columns:
  - name: Station
    attr_as_list: stations
    modify: x.brand
  - name: Diesel
    attr_as_list: stations
    modify: Math.abs(x.diesel).toFixed(2)
  - name: E5
    attr_as_list: stations
    modify: Math.abs(x.e5).toFixed(2)
  - name: Distance
    attr_as_list: stations
    modify: x.dist

But how can I sort on, let's say, the diesel price? Looking at the code it seems that only sensor attribute names are supported. It looks for a value in the attr, prop or attr_as_list field, but the latter always has stations as a value.

riker09 commented 5 years ago

I think I could just split the JSON payload to different attributes (e.g. diesel, e5, distance, ...) and then use that as value for attr_as_list, but that feels like the wrong way to go.

daringer commented 5 years ago

mmh, yes the "modify" attribute was initially intended as a formatting operation, thus it is applied after sorting was done. It would actually not be a big deal to move it, but I am currently not fully convinced if this might not break something---or at least change the behavior for most people using modify and sort together. I'll first move it, push it in a branch then you can check if it behaves as you would expect....

daringer commented 5 years ago

ahhhh, noooo, forget what I've written there, my code confuses me sometime if I haven't seen it for more than 1hour :smile: The problem is---as you also already implied---that the correct column can simply not be identified for sorting, thus all are sorted as they are all identified with the same identifier, namely stations here. Once understood this is easy to fix, I'll just add the possibility to override the implicit identifier derived from the attr_to_list parameter.

hope it works for you, literally one single word added to make it work from functional point of view. Anyways like how you "exploited" the modify param, this cries for a json param to provide a more specific solution for exactly this use-case.

If the id solution works for you, feel free to close the issue, thanks

daringer commented 5 years ago

btw. think you just would have to change your config like this:

sort_by: diesel_price-
...
columns:
  ...
  - name: Diesel
    attr_as_list: stations
    id: diesel_price
    modify: Math.abs(x.diesel).toFixed(2)

Keep in mind that toFixed() will convert to a string, means string-sorting applies and not number-based sorting (likely not an issue for diesel). To avoid this problem you could just add another hidden column without toFixed() and sort by this one, while this column here would be its string representation.

riker09 commented 5 years ago

I cannot test the changes right now (worky, worky) but I'll look into them later. Hopefully today.

riker09 commented 5 years ago

Okay, haven't had the time to check it out yesterday. But today: Great success!

flex-table-card-sorter

Thank you very much!