Table on front-end

I wish to display a table of rail times (from a sensor) on the front end - something like below. Ideally a single sensor (with an attribute consisting of a list of dicts, with each dict containing ‘Due’, ‘Destination’ etc for a single train) would be passed to the table object. Is this possible?

Currently creating a group of individual sensors but not attractive. - bit ugly.

I guess it should be possible by creating a custom card for this purpose, check out this pages:
https://home-assistant.io/developers/frontend_creating_custom_ui/

1 Like

Thanks! I don’t see an example matching what I described, so if anyone has one that could get me started that would be great

I tried to quickly cook something up, but I haven’t tested it yet (don’t have a HA dev env right now).
Try something like this:

<link rel="import" href='./bower_components/brainy-table/brainy-table.html'>

<dom-module id='ha-table-card'>
  <template>
    <brainy-table items="[[stateObj.attributes.next_trains]]" page-size="5">
      <brainy-table-column name="Status">
        <template>[[item.status]]</template>
      </brainy-table-column>
      <brainy-table-column name="Origin">
        <template>[[item.origin_name]]</template>
      </brainy-table-column>
      <brainy-table-column name="Estimated">
        <template>[[item.estimated]]</template>
      </brainy-table-column>
      <brainy-table-column name="Scheduled">
        <template>[[item.scheduled]]</template>
      </brainy-table-column>
      <brainy-table-column name="Platform">
        <template>[[item.platform]]</template>
      </brainy-table-column>
    </template>
</dom-module>
<script>
Polymer({
  is: 'ha-table-card',
  properties: {
    hass: {
      type: Object,
    },

    stateObj: {
      type: Object
    }
  },
});
</script>

This requires you to install https://owox.github.io/brainy-table/components/brainy-table/ using bower, inside the www/custom_ui folder
You can check that library for extra functions (like sorting, filtering etc)

2 Likes

Thanks @tmatheussen will post how I get on!

1 Like

@robmarkcole did you manage to get this working?

Hi didn’t get around to it yet, many projects! Did you try?

Not yet, will definitely be giving it a go as i have exactly the same issue as you have with the presentation of the train times.

1 Like

@robmarkcole
I gave it a go, couldn’t get it working though :frowning: Just came up as a badge on each screen.

Got a screenshot?

I now actually have somewhat the same need, for my crypto currency tracker.
I tried my solution with the Brainy Table, but due to how Polymer is imported in that library, it can’t be used.
Right now, I’ve did it with a generic table in my instance, you can see a screenshot of a first version below:


As you can see, this is stil quite ugly, but it’s a start, I’ll be adding more columns and styling soon.
My code and data structure are not on my GitHub yet, but this is the gist off it:

<dom-module id="state-card-crypto_profit">
  <template>
    <table>
      <thead>
        <tr>
          <th>Token</th>
          <th>Amount</th>
        </tr>
      </thead>
      <tbody>
        <template is="dom-repeat" items="{{stateObj.attributes.coins}}">
          <tr>
            <td>{{item.token}}</td>
            <td>{{item.amount}}</td>
          </tr>
        </template>
      </tbody>
    </table>
  </template>
</dom-module>

<script>
Polymer({
  is: 'state-card-crypto_profit',
  
  properties: {
    hass: {
      type: Object,
    },
    
    stateObj: {
      type: Object,
    },
  }
});

As you can see, I use stateObj.attributes.coins as items input, that’s because my attributes looks like this:

{
  "friendly_name": "Crypto Profit",
  "invested": 1331.8246080099339,
  "coins": [
    {
      "price": 169.58,
      "token": "ETH",
      "initial": 97.00788288200002,
      "amount": 0.5720479,
      "current": 172.67650317100487
    },
    {
      "price": 199.26,
      "token": "ETH",
      "initial": 386.7958026306,
      "amount": 1.94116131,
      "current": 585.9525873648814
    },
    {
      "price": 36.1,
      "token": "LTC",
      "initial": 500.010928825,
      "amount": 13.85071825,
      "current": 709.1397096620267
    },
    {
      "price": 0.49365,
      "token": "IOT",
      "initial": 48.009993680502,
      "amount": 97.25512748,
      "current": 66.559968834741
    },
    {
      "price": 0.2629219997,
      "token": "XEM",
      "initial": 99.99999998673373,
      "amount": 380.340938,
      "current": 89.46357535877377
    },
    {
      "price": 8.888229975,
      "token": "PART",
      "initial": 200.0000000050983,
      "amount": 22.501668,
      "current": 194.80125252248922
    }
  ],
  "total": 1818.593596913917,
  "unit_of_measurement": "EUR",
  "custom_ui_state_card": "crypto_profit"
}

For this to work I needed to add this sensor in a group, so keep that in mind as well :wink:

EDIT: Updated version:

Actually pretty quick and dirty, just playing with some CSS classes:

<style>
  table {
    width: 100%;
  }
  tr:nth-child(even) {
    background-color: #dddddd;
  }
  td, th {
    text-align: left;
  }
</style>

<table>
  <thead>
    <tr>
      <th>Token</th>
      <th>Amount</th>
    </tr>
  </thead>
  <tbody>
    <template is="dom-repeat" items="{{stateObj.attributes.coins}}">
      <tr>
        <td>{{item.token}}</td>
        <td>{{item.amount}}</td>
      </tr>
    </template>
  </tbody>
</table>

Nice! This looks ideal for displaying the train data

Any chance of getting this up on github with a README of instructions? Be great to get this up!

I currently have my repo located here:

I don’t have a lot of documentation/readme’s updated right now.
The basic gist of it:

I’ve named my sensor crypto_profit, added it to a group (needed to display the sensor in a card), set customize on the sensor entry (not the group).
The name I’ve used for my file is state-card-crypto_profit, so my customize entry looks like this:

sensor.crypto_profit:
  custom_ui_state_card: crypto_profit

As you can see in the html file (www/custom_ui/), the id on the dom-module, is the same as the filename, as well as the identifier in the Polymer code.

I hope this covers the most basic setup, you can remove the table from the HTML code, and put anything random (like ‘Hello World!’), to test if the custom UI is being picked up.

1 Like

Thanks for the post, have made a promising start, although needs some tweaking!
Docs for this platform https://home-assistant.io/components/sensor.uk_transport/ and here the attribute next_trains is a list of upcoming train, each of which has attributes origin_name etc. So my goal is to have each item in next_trains in a different row, with attributes displayed in the columns.

For whatever reason, the table is only showing two attributes, and also putting upcoming trains across the table, rather than down the table. I’m a newb to CSS so appreciate any tips :slight_smile:

image

    <table>
      <thead>
        <tr>
          <th>origin_name</th>
          <th>destination_name</th>
          <th>scheduled</th>
          <th>status</th>
          <th>estimated</th>
          <th>platform</th>
          <th>operator_name</th>
        </tr>
      </thead>
      <tbody>
        <template is="dom-repeat" items="{{stateObj.attributes.next_trains}}">
            <td>{{item.origin_name}}</td>
            <td>{{item.destination_name}}</td>
            <td>{{item.scheduled}}</td>
            <td>{{item.status}}</td>
            <td>{{item.estimated}}</td>
            <td>{{item.platform}}</td>
            <td>{{item.operator_name}}</td>
        </template>
      </tbody>
    </table>

Missing Table Rows:

<table>
  <thead>
    <tr>
      <th>origin_name</th>
      <th>destination_name</th>
      <th>scheduled</th>
      <th>status</th>
      <th>estimated</th>
      <th>platform</th>
      <th>operator_name</th>
    </tr>
  </thead>
  <tbody>
    <template is="dom-repeat" items="{{stateObj.attributes.next_trains}}">
        <tr>
            <td>{{item.origin_name}}</td>
            <td>{{item.destination_name}}</td>
            <td>{{item.scheduled}}</td>
            <td>{{item.status}}</td>
            <td>{{item.estimated}}</td>
            <td>{{item.platform}}</td>
            <td>{{item.operator_name}}</td>
        </tr>
    </template>
  </tbody>
</table>
1 Like

Looks identical to what I posted or am I missing something…? :thinking:

EDIT: needed the

Missing two tiny tags

<tr> </tr>

(Table Row)

1 Like

I must be still missing something since I see:

image

<dom-module id="state-card-uk_transport">
  <template>

    <style>
      table {
        width: 100%;
      }
      tr:nth-child(even) {
        background-color: #dddddd;
      }
      td, th {
        text-align: left;
      }
    </style>

    <p>
      <b>Next_train:</b> {{round(stateObj.state)}}
    </p>

    <table>
      <thead>
        <tr>
          <th>origin_name</th>
          <th>destination_name</th>
          <th>scheduled</th>
          <th>status</th>
          <th>estimated</th>
          <th>platform</th>
          <th>operator_name</th>
        </tr>
      </thead>
      <tbody>
        <template is="dom-repeat" items="{{stateObj.attributes.next_trains}}">
            <tr>
                <td>{{item.origin_name}}</td>
                <td>{{item.destination_name}}</td>
                <td>{{item.scheduled}}</td>
                <td>{{item.status}}</td>
                <td>{{item.estimated}}</td>
                <td>{{item.platform}}</td>
                <td>{{item.operator_name}}</td>
          <tr>
        </template>
      </tbody>
    </table>
  </template>
</dom-module>

<script>
Polymer({
  is: 'state-card-uk_transport',

  properties: {
    hass: {
      type: Object,
    },

    stateObj: {
      type: Object,
    },
  },

});
</script>

Your </tr> closing tag is incorrect, you’ve got it as a second opening tag (<tr>)

        <td>{{item.operator_name}}</td>
    </tr>
</template>
1 Like