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

How to reference JSON key with whitespace #112

Open brad-newman opened 8 months ago

brad-newman commented 8 months ago

I have a sensor that spits out the following (for example):

day_1: Day: Wed 18 Tides: 1st Tide: Time: 4:06am Height: 4.27 ft 2nd Tide: Time: 8:05am Height: 2.95 ft

I've tried a few ways to reference, e.g., day_1.Tides."1st Tide".Time but I can't seem to get it to work...

EdLeckert commented 8 months ago

Does the sensor supply JSON or just the text you supplied?

brad-newman commented 8 months ago

Sensor supplies it in JSON format, which is what I pasted (but I couldn't figure out how to maintain the spacing).

EdLeckert commented 8 months ago

Screen shot?

brad-newman commented 8 months ago

Here you go: image

EdLeckert commented 8 months ago

So there's an attribute for each day?

Can you put this in your Developer Tools/Template, substituting your sensor name, and paste the result here?

{{ state_attr("<sensor_name>","day_1") }}

brad-newman commented 8 months ago

Done: image

EdLeckert commented 8 months ago

I'm not an expert, but I don't think you can do this directly. However, I've come up with two options. One is to display them in a single row:

Tides

The card definition is:

type: custom:flex-table-card
entities:
  - sensor.tide_data
columns:
  - name: Day
    data: day_1
    modify: x.Day
  - name: 1st Tide
    data: day_1.Tides.1st Tide
    modify: x.Time || ""
  - name: Height
    data: day_1.Tides.1st Tide
    modify: x.Height || ""
  - name: 2nd Tide
    data: day_1.Tides.2nd Tide
    modify: x.Time || ""
  - name: Height
    data: day_1.Tides.2nd Tide
    modify: x.Height || ""
  - name: 3rd Tide
    data: day_1.Tides.3rd Tide
    modify: x.Time || ""
  - name: Height
    data: day_1.Tides.3rd Tide
    modify: x.Height || ""
  - name: 4th Tide
    data: day_1.Tides.4th Tide
    modify: x.Time || ""
  - name: Height
    data: day_1.Tides.4th Tide
    modify: x.Height || ""

If there are fewer than four tides, those columns will show as blank.

The second method is to convert the JSON into a structure that flex-table can iterate on. It seems to like either a list of entities or an attribute in a single entity that contains a list. For the latter you can create a template sensor in configuration.yaml:

template:
  - sensor:
      - name: Tides
        state: '{{ state_attr("input_text.tides","day_1").Day }}'
        attributes:
          day_1: >
            [
                {{ state_attr("sensor.tide_data","day_1").Tides["1st Tide"] }},
                {{ state_attr("sensor.tide_data","day_1").Tides["2nd Tide"] }},
                {{ state_attr("sensor.tide_data","day_1").Tides["3rd Tide"] }},
                {{ state_attr("sensor.tide_data","day_1").Tides["4th Tide"] }}
            ]

Then the card definition is:

type: custom:flex-table-card
entities:
  - sensor.tides
columns:
  - name: Tides
    data: day_1
    modify: x.Time
  - name: Height
    data: day_1
    modify: x.Height

This gives you: TidesByRow

I realize neither of these is ideal, but perhaps it will give you some inspiration.

And if anyone else has a better solution, please chime in!

brad-newman commented 8 months ago

This is great, thanks very much!