Her er et annet løsningsforslag, men jeg er ikke veldig fornøyd med det.
Jeg ville egentlig hente data fra et egetutviklet API. API'et er ferdig, men jeg finner ingen god måte å dynamisk hente data fra det og vise det i lovelace uten å gå via en sensor. Ulempen med å gå via sensor er at HA blir merkbart tregere når det foreligger store json-objekter i developer->states.
command_line:
- sensor:
name: Gas Prices
command: >
app_id="com.raskebiler.drivstoff.appen.android";
api_brands="https://api.drivstoffappen.no/api/v1/brands";
api_sessions="https://api.drivstoffappen.no/api/v1/authorization-sessions";
api_stations="https://api.drivstoffappen.no/api/v1/stations?stationTypeId=1&includeDeleted=true&includePending=true&minUpdatedAt={{ (now() - timedelta(days=2)).strftime('%Y-%m-%dT%H:%M:%S%z') | urlencode }}";
auth_token=$(curl -s $api_sessions | jq -r ".token");
api_key=$(python -c "import hashlib; auth_token = \"$auth_token\"; shifted_auth_token = bytearray(auth_token, 'utf-8')[1:] + bytearray(auth_token, 'utf-8')[:1]; print(hashlib.md5(shifted_auth_token).hexdigest())");
stations=$(curl -s -H "X-API-KEY: $api_key" -H "X-CLIENT-ID: $app_id" $api_stations);
brands=$(curl -s -H "X-API-KEY: $api_key" -H "X-CLIENT-ID: $app_id" $api_brands);
merged=$(jq -s '[.[0][] as $stations | .[1][] as $brands | select($stations.brandId == $brands.id) | $stations | .brand = $brands]' <(echo "$stations") <(echo "$brands"));
echo "{\"stations\": $(echo "$merged") }"
json_attributes:
- stations
value_template: 'OK'
scan_interval: 1800
input_select:
gas_prices_sort:
name: Sort by
options:
- Last updated
- Distance
- Petrol
- Diesel
initial: Distance
icon: mdi:sort
Her er min lovelace implementasjon. Det jeg synes er kult er at den alltid viser stasjoner som er nærme din nåværende posisjon.
type: custom:vertical-stack-in-card
cards:
- type: entities
title: Gas prices
style: |
.card-content { padding: 0 !important; }
entities:
- entity: input_select.gas_prices_sort
- type: markdown
content: >
{% set data = namespace(stations=[]) %}
{%- set current_person = states.person|selectattr("attributes.friendly_name", "==", user) | map(attribute="entity_id") | first | default("zone.home") -%}
{%- set stations = state_attr("sensor.gas_prices", "stations") -%}
{%- for item in stations -%}
{%- set station_distance = distance(item.latitude, item.longitude, current_person) -%}
{%- if station_distance <= 5.0 and
item.prices | selectattr("fuelTypeId", "eq", 1) | map(attribute="price") | first | default(None) and
item.prices | selectattr("fuelTypeId", "eq", 2) | map(attribute="price") | first | default(None) -%}
{% set data.stations = data.stations + [{
"id": item.id,
"name": item.name,
"location": item.location,
"pictureUrl": item.brand.pictureUrl,
"updatedAt": item.updatedAt,
"distance": station_distance|round(1),
"priceType95": item.prices | selectattr("fuelTypeId", "eq", 2) | map(attribute="price") | first | default(0.0),
"priceTypeD": item.prices | selectattr("fuelTypeId", "eq", 1) | map(attribute="price") | first | default(0.0),
}]
%}
{%- endif -%}
{%- endfor %}
{% if is_state('input_select.gas_prices_sort', 'Last updated') %}
{%- set data.stations = data.stations | sort(attribute='updatedAt', reverse = True) -%}
{% elif is_state('input_select.gas_prices_sort', 'Distance') %}
{%- set data.stations = data.stations | sort(attribute='distance') -%}
{% elif is_state('input_select.gas_prices_sort', 'Petrol') %}
{%- set data.stations = data.stations | sort(attribute='priceType95') -%}
{% elif is_state('input_select.gas_prices_sort', 'Diesel') %}
{%- set data.stations = data.stations | sort(attribute='priceTypeD') -%}
{% endif %}
<table>
<thead>
<th colspan="2">Gas station</th>
<th>Diesel</th>
<th>Petrol</th>
</thead>
<tbody>
{%- for item in data.stations[:5] -%}
<tr>
<td rowspan="2"><img src="{{ item.pictureUrl }}" width="40"></td>
<td rowspan="2">
<h1>{{ item.name }}</h1>
{{ item.location|replace(',', '<br/>', 1) }} ({{ item.distance }} Km)
</td>
<td>{{ "%0.2f"|format(item.priceTypeD) + ',-' if item.priceTypeD > 0.0 else '-' }}</td>
<td>{{ "%0.2f"|format(item.priceType95) + ',-' if item.priceType95 > 0.0 else '-' }}</td>
</tr>
<tr>
<td colspan="2">{{ relative_time(as_datetime(item.updatedAt)) + " ago" }}</td>
</tr>
{%- endfor %}
</tbody>
</table>
card_mod:
style:
ha-markdown $: |
table {
width: 100%;
}
tbody tr:nth-child(4n-2),
tbody tr:nth-child(4n-3) {
background-color: var(--table-row-background-color);
}
tbody tr:nth-child(4n-1),
tbody tr:nth-child(4n-0) {
background-color: var(--table-row-alternative-background-color);
}
tbody tr:nth-child(odd) td:nth-child(1) {
background-color: #fff;
padding-right: 10px;
}
td h1 {
font-size: 1.2em;
font-weight: normal;
}
tbody td:nth-child(2) {
padding: 0 10px 5px 10px;
}
tbody td:nth-last-child(-n+2) {
text-align: center;
}
tbody tr:nth-child(odd) td:nth-last-child(-n+2) {
font-size: 1.4em;
padding: 5px;
}
tbody tr:nth-child(even) td:nth-last-child(-n+2) {
font-style: italic;
}
Skjermbilde: