djtimca
(Tim)
November 25, 2020, 9:39pm
1
Back with some more space stuff… if you have ever been interested in tracking satellites or like to know when the ISS is going to pass over head I’ve built an integration for that.
This integration can be added as either:
Satellite Tracker
Location Tracker
The Satellite Tracker will add 5 sensors for the next 5 visible passes of the satellite over your specified location (defaults to ISS and your Home Assistant home location). It will also add a device tracker sensor which will allow you to see where the satellite is on your map at any given time.
The Location Tracker will add one sensor which gives you a count of how many satellites are visible over head and in the attributes will list the details of those satellites (name, location, etc).
You can add multiple integrations so you can have one (or more) of each.
Note: The API used for this integration (N2YO.com ) has rate limits so if you add too many integrations and/or set your polling interval too low you will wind up banned.
Any feedback let me know!
7 Likes
djtimca
(Tim)
November 27, 2020, 7:04pm
2
If you’re looking for a Lovelace layout for the info here’s what I’m using (for Satellite Tracker) which uses the custom:button-card from HACS and Gauge Cards:
type: vertical-stack
title: ISS Passes
cards:
- type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_0
name: Next Pass
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan"
case 1:
month = "Feb"
case 2:
month = "Mar"
case 3:
month = "Apr"
case 4:
month = "May"
case 5:
month = "Jun"
case 6:
month = "Jul"
case 7:
month = "Aug"
case 8:
month = "Sep"
case 9:
month = "Oct"
case 10:
month = "Nov"
case 11:
month = "Dec"
};
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_0
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_0
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_1
name: Pass 2
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan"
case 1:
month = "Feb"
case 2:
month = "Mar"
case 3:
month = "Apr"
case 4:
month = "May"
case 5:
month = "Jun"
case 6:
month = "Jul"
case 7:
month = "Aug"
case 8:
month = "Sep"
case 9:
month = "Oct"
case 10:
month = "Nov"
case 11:
month = "Dec"
};
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_1
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_1
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_2
name: Pass 3
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan"
case 1:
month = "Feb"
case 2:
month = "Mar"
case 3:
month = "Apr"
case 4:
month = "May"
case 5:
month = "Jun"
case 6:
month = "Jul"
case 7:
month = "Aug"
case 8:
month = "Sep"
case 9:
month = "Oct"
case 10:
month = "Nov"
case 11:
month = "Dec"
};
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_2
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_2
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_3
name: Pass 4
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan"
case 1:
month = "Feb"
case 2:
month = "Mar"
case 3:
month = "Apr"
case 4:
month = "May"
case 5:
month = "Jun"
case 6:
month = "Jul"
case 7:
month = "Aug"
case 8:
month = "Sep"
case 9:
month = "Oct"
case 10:
month = "Nov"
case 11:
month = "Dec"
};
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_3
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_3
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_4
name: Pass 5
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan"
case 1:
month = "Feb"
case 2:
month = "Mar"
case 3:
month = "Apr"
case 4:
month = "May"
case 5:
month = "Jun"
case 6:
month = "Jul"
case 7:
month = "Aug"
case 8:
month = "Sep"
case 9:
month = "Oct"
case 10:
month = "Nov"
case 11:
month = "Dec"
};
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_4
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_4
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
For the location integration I just use an entity card which shows me how many satellites overhead, then I can click on it for the details of what is there:
bb12489
(Bb12489)
December 3, 2020, 6:15am
3
Thanks so much for this integration! I have it up and running showing me exactly where the ISS is and when it’s passing by. As for the location sensor for tracking which satellites are passing over; I was hoping to track Starlink sats specifically. I see that you can choose a category when configuring the location sensor, but the Starlink category isn’t available. N2YO shows Starlink as category ID 52. Can this be added to your integration?
Thanks!
djtimca
(Tim)
December 3, 2020, 2:22pm
4
Just released 0.0.2 which now includes the Starlink category for location tracking. Enjoy!
bb12489
(Bb12489)
December 3, 2020, 11:06pm
6
So I’m trying to setup the Location integration, but when I get to the end after configuring which category to track and click submit, it just says “Aborted”. Any clue?
bb12489
(Bb12489)
December 3, 2020, 11:45pm
8
Nothing obvious seems to stick out in the logs anywhere. Although I could be looking in the wrong spots.
My previous integrations for the ISS and Satellite tracking (tracking all), still seems to work. I just can’t seem to setup a third one.
djtimca
(Tim)
December 4, 2020, 12:01am
9
I think I may know what it is. I believe I use the latitude and longitude as the key for the instance of the integration. So adding a second location tracker with a different category may fail as already set up. Will look tomorrow and if that’s the case I will just add the category to the key which should fix that. Will let you know.
bb12489
(Bb12489)
December 4, 2020, 12:02am
10
Awesome, thanks for looking into it.
djtimca
(Tim)
December 4, 2020, 1:45am
11
OK @bb12489 - found some time tonight. Fix is pushed as an update. You may need to remove and re-add your location integrations, but you should now be able to add multiple location integrations from the same location as long as they are for different satellite categories. Give it a shot.
bb12489
(Bb12489)
December 4, 2020, 2:01am
12
Just tried it, and it looks like it’s working as it should! Thanks again for your help. Showing about 36 Starlink sats above me right now!
mtee
January 15, 2021, 6:03am
13
I’ve scored points with my wife with this integration. It’s fun and we’re looking forward to using it. However my Next Pass dates are showing up 11 months in advance, showing 12-16-2021 while it’s 1-15-21. Am I overlooking something? I believe this is affecting automations for alerts.
Thanks!!
Screen Shot 2021-01-15 at 12.59.33 AM|368x500
djtimca
(Tim)
January 15, 2021, 11:27am
14
I didn’t even notice on mine! Won’t be affecting automations (or shouldn’t) because if you click on the pass the dates look to be appearing correctly. Might be related to the JavaScript in the card itself. Will look at it today and see if I can sort it out and will either push an update or post an update to the card script here.
djtimca
(Tim)
January 15, 2021, 2:32pm
15
OK - looks like bad JavaScript in my card! I’ve updated below (and also added some additions like all cards are conditional now and if you have no visible passes coming it will show just that notification as well).
type: vertical-stack
title: ISS Passes
cards:
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_0
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_0
name: Next Pass
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(1611013785 * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_0
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_0
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_1
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_1
name: Pass 2
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(1611013785 * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_1
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_1
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_2
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_2
name: Pass 3
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(1611013785 * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_2
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_2
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_3
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_3
name: Pass 4
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(1611013785 * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_3
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_3
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_4
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_4
name: Pass 5
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(1611013785 * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_4
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_4
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_0
state: unknown
card:
type: markdown
content: There are no visible passes coming up.
mtee
January 15, 2021, 7:07pm
16
Thanks very much, Tim. I appreciate it very much. We’re looking forward to having fun with it.
fjt1973
(Francis Taylor)
January 23, 2021, 9:50pm
17
Mmmmm not so sure. New to HA so copied your code above and this is my card.
Love the fact that the code went in first time but todays date is the 23rd January.
Where has the 18th come from?
fjt1973
(Francis Taylor)
January 23, 2021, 10:41pm
18
Sussed it… in the above config (the one posted 8 days ago) you have the following line of configuration:
var passdate = new Date(1611013785 * 1000);
But in the original config you had this line of configuration:
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
So I’ve put this line “var passdate = new Date(entity.attributes.pass_start_unix * 1000);” back in and all is good
1 Like
djtimca
(Tim)
January 24, 2021, 3:28am
19
Nice catch!!
So I’ve updated - proper card config would be:
type: vertical-stack
title: ISS Passes
cards:
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_0
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_0
name: Next Pass
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_0
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_0
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_1
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_1
name: Pass 2
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_1
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_1
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_2
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_2
name: Pass 3
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_2
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_2
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_3
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_3
name: Pass 4
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_3
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_3
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_4
state_not: unknown
card:
type: horizontal-stack
cards:
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_4
name: Pass 5
show_label: false
styles:
card:
- width: 250px
- height: 100%
grid:
- grid-template-areas: '"n date" "i time" "i duration"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: min-content min-content min-content
name:
- align-self: start
- justify-self: center
- font-weight: bold
icon:
- width: 40px
custom_fields:
date:
- align-self: start
- justify-self: start
- font-size: 14px
time:
- align-self: start
- justify-self: start
- font-size: 14px
duration:
- align-self: start
- justify-self: start
- font-size: 14px
startdir:
- align-self: start
- justify-self: start
- font-size: 14px
enddir:
- align-self: start
- justify-self: start
- font-size: 14px
custom_fields:
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var day = passdate.getDate();
var month = "";
var year = passdate.getFullYear();
switch(passdate.getMonth()) {
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
}
return day + "-" + month + "-" + year
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var hours = passdate.getHours();
var minutes = "0" + passdate.getMinutes();
var ampm = "am";
if (hours > 12) {
hours = hours - 12
ampm = "pm"
}
return hours + ":" + minutes.substr(-2) + " " + ampm
]]]
duration: |
[[[
return entity.state + " seconds"
]]]
- type: vertical-stack
cards:
- type: 'custom:gauge-card'
entity: sensor.international_space_station_iss_pass_4
attribute: max_elevation
measurement: °
scale: 15px
severity:
red: 0
yellow: 45
green: 65
- type: 'custom:button-card'
entity: sensor.international_space_station_iss_pass_4
show_icon: false
show_name: false
styles:
grid:
- grid-template-areas: '"path"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
custom_fields:
path:
- align-self: start
- font-size: 14px
custom_fields:
path: |
[[[
return entity.attributes.start_compass + " > " + entity.attributes.end_compass
]]]
- type: conditional
conditions:
- entity: sensor.international_space_station_iss_pass_0
state: unknown
card:
type: markdown
content: There are no visible passes coming up.
1 Like
DrMurx
February 1, 2021, 4:18pm
20
The card configuration can be simplified with the DateTimeFormat object which is available in all modern browsers, with the positive side effect of allowing the user to pick a locale other than en-US easily.
date: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var options = { year: 'numeric', month: 'short', day: 'numeric' };
return new Intl.DateTimeFormat('en-US', options).format(passdate);
]]]
time: |
[[[
var passdate = new Date(entity.attributes.pass_start_unix * 1000);
var options = { hour: '2-digit', minute: '2-digit' };
return new Intl.DateTimeFormat('en-US', options).format(passdate);
]]]
2 Likes