amaximus / bkk-stop-card Goto Github PK
View Code? Open in Web Editor NEWCustom Lovelace card for Budapest Public Transportation custom component
Custom Lovelace card for Budapest Public Transportation custom component
Hi!
Is it possible to add the configuration option to show X number of future rides from a given station?
The current Y minutes into the future option makes the card resize, which can break the aesthetic of some dashboard configurations.
Hi Aximus!
Just sharing a tablet compatible version of the card that might be useful for someone being late for the bus by highlighting the vehichle number and the arrival time. I've been using it for a couple of months on a tablet placed next to the front door. Hope you find it useful for the next major update or a separate version.
Complete modified source code (bkk-stop-card.js):
class BKKStopCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
_getAttributes(hass,entity) {
var res = [];
var bikes = "";
var icon;
var max_items = this._config.max_items;
var nr_of_items;
var vehicle;
var wheelchair = "";
if (typeof hass.states[`${entity}`] != "undefined") {
const data1 = hass.states[`${entity}`].attributes['vehicles'];
const station = hass.states[`${entity}`].attributes['stationName'];
if (data1.length > 0) {
nr_of_items= max_items > 0 ? Math.min(data1.length,max_items) : data1.length;
for(var i=0; i<nr_of_items; i++) {
if (data1[i].hasOwnProperty('wheelchair')) {
wheelchair='<ha-icon icon="mdi:wheelchair-accessibility" class="extraic">';
}
if (data1[i].hasOwnProperty('bikesAllowed')) {
bikes='<ha-icon icon="mdi:bike" class="extraic">';
}
icon=data1[i].type.toLowerCase();
vehicle=icon;
if (icon == "trolleybus") {
icon="bus"
} else if (icon == "rail") {
icon="train"
}
res.push({
attime: data1[i].attime,
predicted_attime: data1[i].predicted_attime,
bikes: bikes,
headsign: data1[i].headsign,
inmin: data1[i].in,
icon: icon,
key: data1[i].routeid,
station: station,
vehicle: vehicle,
wheelchair: wheelchair,
});
}
} else {
res.push({
key: 'No service',
vehicle: '',
inmin: 'following',
headsign: 'any destination',
wheelchair: '',
bikes: '',
icon: '',
attime: '',
predicted_attime: '',
station: station
});
}
}
return res;
}
setConfig(config) {
if (!config.entity) {
throw new Error('Please define an entity');
}
config.filter
const root = this.shadowRoot;
if (root.lastChild) root.removeChild(root.lastChild);
const cardConfig = Object.assign({}, config);
const card = document.createElement('ha-card');
const content = document.createElement('div');
const style = document.createElement('style');
style.textContent = `
h3 {
text-align: center;
}
table {
width: 100%;
padding: 0px 36px 16px 0px;
border: none;
margin-left: 16px;
margin-right: 16px;
}
thead th {
text-align: left;
}
td {
padding-left: 5px;
vertical-align: middle;
}
.highlight {
font-weight: bold;
font-size: 150%;
width: 2em;
}
.vehicle {
text-align: center;
padding: 3px 10px 3px 10px;
border-radius: 3px;
color: #ffffff;
}
.emp {
font-weight: bold;
font-size: 120%;
}
.extraic {
width: 1em;
padding-left: 5px;
}
.bus {
background-color: #009FE3;
}
.trolleybus {
background-color: #E5231B;
}
.tram {
background-color: #FFD500;
}
.rail {
background-color: #2ECC71;
}
.subway {
width: 1.5em;
}
.arrival-time {
text-align: right;
}
.estimated {
color: #208C4E;
}
`;
content.innerHTML = `
<p id='station'>
<table>
<tbody id='attributes'>
</tbody>
</table>
`;
card.appendChild(style);
card.appendChild(content);
root.appendChild(card)
this._config = cardConfig;
}
_updateContent(element, attributes, h_in_mins, h_at_time, h_predicted_at_time) {
element.innerHTML = `
${attributes.map((attribute) => `
<tr>
<td class="highlight vehicle ${attribute.vehicle}">${attribute.key}</td>
<td class="">${attribute.headsign}</td>
<td class="highlight arrival-time ${attribute.predicted_attime ? "estimated" : ''}">${attribute.inmin}'</td>
</tr>
`).join('')}
`;
}
_updateStation(element, attributes, name) {
element.innerHTML = `
${attributes.map((attribute) => `
<h3>${name.length === 0 ? `${attribute.station}` : name}</h3>
`)[0]}
`;
}
set hass(hass) {
const config = this._config;
const root = this.shadowRoot;
let hide_predicted_at_time = false;
if (typeof config.hide_predicted_at_time != "undefined") hide_predicted_at_time=config.hide_predicted_at_time
let hide_in_mins = false;
if (typeof config.hide_in_mins != "undefined") hide_in_mins=config.hide_in_mins
let hide_at_time = true;
if (typeof config.hide_at_time != "undefined") hide_at_time=config.hide_at_time
let name = '';
if (typeof config.name != "undefined") name=config.name
let max_items = 0;
if (typeof config.max_items != "undefined") max_items=config.max_items
let attributes = this._getAttributes(hass, config.entity);
this._updateStation(root.getElementById('station'), attributes, name);
this._updateContent(root.getElementById('attributes'), attributes, hide_in_mins, hide_at_time, hide_predicted_at_time);
}
getCardSize() {
return 1;
}
}
customElements.define('bkk-stop-card', BKKStopCard);
While I tested my changes for integration, I found this error in this lovelace card.
https://github.com/amaximus/bkk-stop-card/blob/master/bkk-stop-card.js#L47
The routeobjarray
it's bad, I think the good variable is a res
.
Hello!
Would like to see a "filter" feature to show only certain buses
Usually i only need 1 bus from the specified station, but 5-10 different busses are shown
Dear @amaximus ,
Would it be somehow possible to set the card to calculate the in-mins time from the predicted times when they are available? Currently if in-mins is set to true, it calculates from the scheduled at-time not considering a predicted delay if its available. Also the BKK GO layout works the same, if there is a delay it will not show it in the remaining minutes table.
I am using this integration for Train schedules (when to start heading to the station). Would be great if this could be set up somehow.
Thanks!
I am using the following in configuration.yaml
and this in the custom card configuration:
entity: sensor.bkk_67-bus
type: 'custom:bkk-stop-card'
The card cannot show the detail. It only gives this error:
Undefined
No service to any destination in following mins
Please help, thank you!
If I open a tab in HA where BKK stop card inserted my whole browser (almost) freeze. I profiled the running code and it seems that _getAttributes function takes about 3 seconds to run. Updating of hass object is takes more than once in 3 seconds so thats causes to freeze of the browser. As I checked the code there are nested forEach calls on state and attribute keys. I've printed out and I have a fairly large amount of states (approx 2500) and attributes (approx 10000) in HA. Could you modify the code to work with that large amount of states/attributes?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.