Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sub-object in data selector #86

Open
Veejer opened this issue Sep 16, 2022 · 14 comments
Open

Allow sub-object in data selector #86

Veejer opened this issue Sep 16, 2022 · 14 comments

Comments

@Veejer
Copy link
Contributor

Veejer commented Sep 16, 2022

Suppose I have an attribute named: my_data. My data is an object that contains another object named: more_data. Inside more_data is a field named: my_field. The problem is that the data selector can only access the top object as in:
data: my_field

I can use the modify selector to access the rest of the object as in:
modify: x.more_data.my_field.

However this means that I cannot use the fmt selector and would therefore have to add additional code in the modify selector to format the data.

So, I propose that the data selector be able to use dotted notation to access the correct field. For example:
data: my_data.more_data.my_field

This allows me to use the fmt option if I choose or I can continue to use the modify option to format the x value.
The modification I propose should be flexible enough to allow any number of sub-levels.
This modification should only apply to attributes and not to any other entity key.

Veejer added a commit to Veejer/flex-table-card that referenced this issue Sep 18, 2022
Veejer added a commit to Veejer/flex-table-card that referenced this issue Sep 18, 2022
daringer added a commit that referenced this issue Sep 20, 2022
@jata1
Copy link

jata1 commented Jul 8, 2023

Just checking in to see if this feature has been merged and released. The documentation seems to suggest it has but I can't get it to work. Using modify: x.blar instead but keen to change to this once released.

@ildar170975
Copy link
Contributor

Have you tried smth like this?

      - name: long_state -> subattr
        data: long_state
        modify: >-
          x.subattr

@jata1
Copy link

jata1 commented Jul 9, 2023

Thanks. Yes that is what I currently do and it works fine but thought this solution was better and I would like to avoid using modify: x.subattr

@jata1
Copy link

jata1 commented Jul 9, 2023

In the docs (data column examples), this is included
"When accessing attributes, sometimes an attribute object will itself contain objects. In that case, you can access the lower object using dotted notation. eg: object1.object2.field1"

@ildar170975
Copy link
Contributor

ildar170975 commented Jul 9, 2023

Hmmm, strange, I think I never used this (at least do not remember).
This does not work:
image

@jata1
Copy link

jata1 commented Jul 9, 2023

Yep. I found the same. I think this will be a great addition if/when it gets implemented/released.

I have an entity for connected devices on my LAN that uses nested objects/attributes. So it would literally require - object1.object2.field1

It is working fine using modify so I was just interested to see if I could get it working...

Thanks for helping/discussing this with me :-)

@jata1
Copy link

jata1 commented Jul 9, 2023

one more question. See below for attributes for an entity. For the 'actions' attribute, I want to return the 'data' value. How would I do this?

I have tried the following...

image

image

`weekdays:

  • workday
    timeslots:
  • 00:00:00 - 04:00:00
  • 04:00:00 - 05:30:00
  • 05:30:00 - 19:00:00
  • 19:00:00 - 22:30:00
  • 22:30:00 - 00:00:00
    entities:
  • climate.gas_heater_thermostat
    actions:
  • service: climate.set_preset_mode
    data:
    preset_mode: sleep
  • service: climate.set_preset_mode
    data:
    preset_mode: activity
  • service: climate.set_preset_mode
    data:
    preset_mode: home
  • service: climate.set_preset_mode
    data:
    preset_mode: comfort
  • service: climate.set_preset_mode
    data:
    preset_mode: activity
    current_slot: 2
    next_slot: 3
    next_trigger: '2023-07-10T19:00:00+10:00'
    tags: []
    icon: mdi:calendar-clock
    friendly_name: Gas Heater Weekdays`

@jata1
Copy link

jata1 commented Jul 9, 2023

Please ignore last post - got it working.

image

@ildar170975
Copy link
Contributor

@jata1
Here is a thread for this card, some solutions provided:
https://community.home-assistant.io/t/flex-table-card/461173

@daringer
Copy link
Collaborator

daringer commented Sep 3, 2023

mmmh, for me the following works e.g. for weather:

type: custom:flex-table-card
title: Test-case nested attributes
entities:
  include: weather.*
columns:
  - data: name
  - data: forecast.0.condition

the 0 makes somehow sense, as forcast contains multiple items (objects) with condition ... that's kind of very explicit - not optimal ...

@ildar170975
Copy link
Contributor

ildar170975 commented Sep 3, 2023

@daringer
Assume some attribute is a list (like in the weather entity):
image
Noticed this works:

          - name: value_1
            data: list_attribute.1.value_1

and it creates ONE row for a particular array's element (as it is expected):
image
But I cannot extract data from all array's elements like:

          - name: value_1
            data: list_attribute.value_1

image
Have to use modify then:

  - name: value_1
    data: list_attribute
    modify: x.value_1

image
P.S. As for me, I am rather satisfied with the current behaviour.

@lindsaymarkward
Copy link

lindsaymarkward commented Feb 1, 2025

Hi good people. I see this issue is open after the merged 'fix dot notation' commit.
I'm not sure what I'm missing, but I can't get this to work with a variety of attempts.
Here's my data, from the Nintendo Parental Controls component.

{'daily': [{'deviceId': '..', 'date': '2025-02-01', 'result': 'CALCULATING', 'playingTime': 11700, 'exceededTime': None, 'disabledTime': 0, 'miscTime': 600, 'importantInfos': [], 'notices': [], 'observations': [], 'playedApps': [{'applicationId': '0100853015E86000', 'title': "No Man's Sky", 'imageUri': {'extraSmall': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'small': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'medium': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'large': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'extraLarge': 'https://atum-img-lp1.cdn.nintendo.net/i/c/'}, 'hasUgc': True, 'shopUri': 'https://ec.nintendo.com/apps//AU?lang=en-GB', 'firstPlayDate': '2023-12-25'}], 'anonymousPlayer': None, 'devicePlayers': [{'playerId': '', 'nickname': 'Jii', 'imageUri': 'https://storage.googleapis.com/upload-4fcba637/device_players/5362b5eb-72c5-4a64-a8dd-.jpg?x=', 'playingTime': 10800, 'playedApps': [{'applicationId': '.', 'firstPlayDate': '2023-12-25', 'playingTime': 10800}]}], 'timeZoneUtcOffsetSeconds': 36000, 'lastPlayedAt': 1738395892, 'createdAt': 1738357143, 'updatedAt': 1738395909}, {'deviceId': '..', 'date': '2025-01-31', 'result': 'ACHIEVED', 'playingTime': 3900, 'exceededTime': None, 'disabledTime': 0, 'miscTime': 600, 'importantInfos': [], 'notices': [], 'observations': [], 'playedApps': [{'applicationId': '010089C01E9CA000', 'title': 'SteamWorld Heist II', 'imageUri': {'extraSmall': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'small': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'medium': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'large': 'https://atum-img-lp1.cdn.nintendo.net/i/c/', 'extraLarge': 'https://atum-img-lp1.cdn.nintendo.net/i/c/'}, 'hasUgc': False, 'shopUri': 'https://ec.nintendo.com/apps/010089c01e9ca000/AU?lang=en-GB', 'firstPlayDate': '2024-11-30'}], 'anonymousPlayer': None, 'devicePlayers': [{'playerId': '..', 'nickname': 'Linds', 'imageUri': 'https://storage.googleapis.com/upload-4fcba637/device_players/1be6d1d6-cc8c-415b-bd9f-6e29d0fcf0be.jpg?x=', 'playingTime': 3300, 'playedApps': [{'applicationId': '010089C01E9CA000', 'firstPlayDate': '2024-11-30', 'playingTime': 3300}]}], 'timeZoneUtcOffsetSeconds': 36000, 'lastPlayedAt': 1738313691, 'createdAt': 1738253859, 'updatedAt': 1738357143}, {'deviceId': '..', 'date': '2025-01-30', 'result': 'ACHIEVED', 'playingTime': 0, 'exceededTime': None, 'disabledTime': 0, 'miscTime': 0, 'importantInfos': [], 'notices': [], 'observations': [], 'playedApps': [], 'anonymousPlayer': None, 'devicePlayers': [], 'timeZoneUtcOffsetSeconds': 36000, 'lastPlayedAt': None, 'createdAt': 1738167463, 'updatedAt': 1738253859}], 'unit_of_measurement': 'min', 'device_class': 'duration', 'friendly_name': 'Nintendo Switch Used Screen Time'}

I can access things I want, like the title of the first game with HA templating, like:

{{ states.sensor.nintendo_switch_used_screen_time.attributes['daily'][0].playedApps[0].title }}

Now I need that in my flex-table-card. I copied code from ... somewhere... that used to work and now doesn't. It used the sensor, sensor.nintendo_switch_used_screen_time as the entities value and then column values such as:

    - data: daily.0.playedApps.0.title
      name: Title

This just results in undefinedundefinedundefined (like that, 3 times).

The only thing I can get to work is what's not in a list, like:

    - data: daily.date
      name: Works

So... does the new version's fix work for selecting items in a list and then their attributes? Is there a right way to do this? I've spent an hour trying the various suggestions in issues here, like modify: x.title or using array instead of dot notation, like daily[0].playedApps[0].title.

Thanks in advance :)

@EdLeckert
Copy link
Contributor

Thanks for reporting this interesting case. Sorry for the trouble. I'll take a look.

In the meantime, I can confirm that your example works in v0.7.7. You can roll back to it here.

Also, I was able to get the following to work with v0.7.8, for what it's worth. I could not reduce it to the first item in the array as you did with daily.0, but then flex-table-card is meant to display lists. Without an example of what your table looked like in the past, I can't be sure what you're trying to accomplish. Perhaps an example mockup would be helpful, or at least the entire card definition.

Also, this configuration will not work with the blank data in the 3rd element of the array...I had to delete it.

type: custom:flex-table-card
entities:
  - sensor.nintendo_switch_used_screen_time
columns:
  - name: Title
    data: daily
    modify: x.playedApps[0].title
  - name: Image URI
    data: daily
    modify: x.playedApps[0].imageUri.medium
  - name: Device Nickname
    data: daily
    modify: x.devicePlayers[0].nickname
  - name: Playing Time
    data: daily.playingTime

Image

Another option is to break down the structure using a template sensor. This example (from configuration.yaml) selects only the first element under daily into a new entity:

template:
  - sensor:
      - name: nintendo_device
        unique_id: nintendo_device
        state: 'Not used'
        attributes:
          device: "{{ states.sensor.nintendo_switch_used_screen_time.attributes['daily'][0] }}"

A card definition that works with it is:

type: custom:flex-table-card
entities:
  - sensor.nintendo_device
columns:
  - name: Title
    data: device.playedApps.title
  - name: shopUri
    data: device.playedApps.shopUri
  - name: imageUri
    data: device.playedApps.imageUri
    modify: x.small

Image

@EdLeckert
Copy link
Contributor

@lindsaymarkward: I've submitted the fix for this, but cannot guarantee when or if it will be merged and released. This fix is one line of code if you want to short-circuit the process.

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

No branches or pull requests

6 participants