Files
rsmsn_blog/public/posts/birdnet_homeassistant_part2.html
2024-07-03 18:21:05 -04:00

1027 lines
93 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" dir="auto">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="index, follow">
<title>BirdNET-PI &amp; HomeAssistant: Part 2 | Norm-working Packets 💾</title>
<meta name="keywords" content="homeassistant, diy, selfhosted">
<meta name="description" content="A Follow up from the previous post, this tutorial takes all the sensors we created and loads them into a beautiful dashboard!">
<meta name="author" content="Me">
<link rel="canonical" href="../posts/birdnet_homeassistant_part2.html">
<script defer data-domain="selfhosted.rsmsn.co" src="https://analytics.rsmsn.co/js/script.js"></script>
<link crossorigin="anonymous" href="../assets/css/stylesheet.b609c58d5c11bb90b1a54e04005d74ad1ddf22165eb79f5533967e57df9c3b50.css" integrity="sha256-tgnFjVwRu5CxpU4EAF10rR3fIhZet59VM5Z&#43;V9&#43;cO1A=" rel="preload stylesheet" as="style">
<link rel="icon" href="../favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="../rsmsncircles.ico">
<link rel="apple-touch-icon" href="../apple-touch-icon.png">
<link rel="mask-icon" href="../safari-pinned-tab.svg">
<meta name="theme-color" content="#2e2e33">
<meta name="msapplication-TileColor" content="#2e2e33">
<link rel="alternate" hreflang="en" href="../posts/birdnet_homeassistant_part2.html">
<noscript>
<style>
#theme-toggle,
.top-link {
display: none;
}
</style>
</noscript>
<meta property="og:title" content="BirdNET-PI &amp; HomeAssistant: Part 2" />
<meta property="og:description" content="A Follow up from the previous post, this tutorial takes all the sensors we created and loads them into a beautiful dashboard!" />
<meta property="og:type" content="article" />
<meta property="og:url" content="/posts/birdnet_homeassistant_part2.html" />
<meta property="og:image" content="/birdnet-homeassistant-part2.png" /><meta property="article:section" content="posts" />
<meta property="article:published_time" content="2023-10-04T10:35:23-04:00" />
<meta property="article:modified_time" content="2023-10-04T10:35:23-04:00" /><meta property="og:site_name" content="Self-hosted Norm" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="/birdnet-homeassistant-part2.png" />
<meta name="twitter:title" content="BirdNET-PI &amp; HomeAssistant: Part 2"/>
<meta name="twitter:description" content="A Follow up from the previous post, this tutorial takes all the sensors we created and loads them into a beautiful dashboard!"/>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1 ,
"name": "Posts",
"item": "/posts.html"
}
{
"@type": "ListItem",
"position": 1 ,
"name": "BirdNET-PI \u0026 HomeAssistant: Part 2",
"item": "/posts/birdnet_homeassistant_part2.html"
}
]
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "BirdNET-PI \u0026 HomeAssistant: Part 2",
"name": "BirdNET-PI \u0026 HomeAssistant: Part 2",
"description": "A Follow up from the previous post, this tutorial takes all the sensors we created and loads them into a beautiful dashboard!",
"keywords": [
"homeassistant", "diy", "selfhosted"
],
"articleBody": "Checking for Entities If youre following up on this from my first post, youve already added your AppDaemon script and confirmed that the AppDaemon logs dont show any errors. Now is the true test if its working: do you have the new sensors in HomeAssistant?!\nThe best way to do this is by just type e from any screen in the HomeAssistant UI! That will bring up a list of entities. Start typing “bird” or “birdnet” and you should see the new entities listed there.\nDashboard Overview \u0026 Dependencies Now that we have the correct entities, lets take a look at what were working with. Full disclosure that once I got this working, I havent really revisited it, refactored it, or made any improvements. Im sure youll find ways to use less YAML, but I wanted to get this out there sooner than later!\nIve included the code for all the cards at the bottom of this post. You can find them here. This dashboard is pretty simple, it brings in almost all of the sensors we created in the first post and organizes them in an as-pleasant-as-possible view. Im definitely not a designer, so some of the colors could be worked on…\nSensors in the dashboard:\nOverview Card: sensor.bird_common_name (only used to generate the picture) camera.birdnet_flickr sensor.bird_common_name sensor.bird_science_name Data Card: sensor.bird_time_seen sensor.bird_confidence sensor.bird_last_seen Weather Card: weather.pirateweather Description Card: sensor.birdnet_wiki There are also two HomeAssistant dashboard dependencies that youll need for this dashboard:\nCustom Weather Card Custom Button Card Custom Card Mod Now that weve got that squared away, lets jump into each card.\nOverview Card Youll notice from the few dependencies listed above, that I use this button card. A lot. RomRider did a fantastic job of adding in a ton of flexibility into the card. For the overview card, were taking one of the entities, in this case, bird_common_name and attaching the Flickr picture/sensor to it. Then, on the right, Im displaying the name and common name. Heres the overview cards yaml.\nThe tricky or tedious part of this card is making sure most of the cards attributes (icon, name, state, label) are set to false. Another option for the Common and Scientific name on the right is to use a markdown card. I couldnt get the formatting just right when using that card and some grid-card tricks, so I opted to reuse the super flexible button-card.\nPay attention to the styles for the image (lines 24-40). Those are what keep the border around the image along with the image a certain height and width so that it looks proportional on the page.\nOne additional thing I have been toying with but hadnt finalized was messing with [img_cell][border]. By adding some javascript in that section (see other cards), you could change the color of the border based on another parameter. Perhaps you look at the state of sensor.bird_common_name and if there is the name of a color in there, thats the borders color. Feel free to get crazy and creative with this!\nOverview Card YAML type: horizontal-stack cards: - type: custom:button-card entity: sensor.bird_common_name triggers_update: all show_name: false show_icon: false show_state: false show_label: false styles: card: - background: transparent - border: none - width: 215px - height: 175px custom_fields: picture: card: type: custom:button-card entity: camera.birdnet_flickr show_entity_picture: true show_name: false show_icon: false styles: card: - height: 100% - width: 100% - padding: 0px 15px 0px 15px - border-radius: 3px 3px 15px 3px - border: none - background: transparent - overflow: visible img_cell: - width: 180px - height: 160px - border-radius: 69% - border: 3px solid grey entity_picture: - width: 215px - height: 100% - type: vertical-stack cards: - type: custom:button-card entity: sensor.bird_common_name show_entity_picture: true show_state: true show_name: false show_icon: false styles: card: - background: transparent - border: none - margin-top: 35px - font-size: 25px - width: auto - type: custom:button-card entity: sensor.bird_science_name show_entity_picture: true show_state: true show_name: false show_icon: false styles: card: - background: transparent - border: black - width: auto Data Card This card is fairly straight forward in that its showing 3 key data points: the time of detection, detection confidence, how long ago it was seen. This could be fairly redundant since we already have the time of detection, but when youre just quickly glancing at the dashboard, minutes ago is much faster brain processing than comparing the timestamp and the current time.\nYouve likely picked up by now that in the previous post, we never sent a payload to create the sensor.bird_last_seen entity. Heres how you can do it.\nCreating Bird Last Seen Entity When I first set out to create this sensor, I was messing with jinja templates for timestamp, datetime, strptime, and more. Here are a few code blocks I saved in my notes in case I went too far down the wrong path. Here are a few of them.\n{{ now() - state_attr(sensor.bird_time_seen, 'last_triggered') \u003e timedelta(hours=24) }} or:\n{% set bird = strptime(states('sensor.bird_time_seen'), \"%H:%M:%S\") %} {{ relative_time(bird) }} The thing is, HomeAssistant has already implemented this really neat feature for calculating time, especially from when something was last updated. This function is called relative_time. Having something like this allows you set automations to run after a specific amount of time has passed since the last time a sensor or entity was updated.\nAn idea! 💡 For our specific use case, you could set up an automation that sends you a notification if no birds have been detected for over 30 minutes. Of course, well set parameters like not to notify you at night or during the winter months.\nThe issue I faced with relative time has to do with the sensors I created from my AppDaemon script. Relative time expects a date and time. I was only passing the time. In Home Assitant if you use the Developer Tools \u003e Template to test relative time out on the sensor.bird_time_seen sensor, youll get a result of 126 years… Thats because without a date, Home Assistant defaults the date to 1900-01-01. The full relative_time return is 1900-01-01 15:15:15.\nWe could go back and set the sensors to include both date and time, but I prefer them separate so that I can use them in different places. For this dashboard, the day is always today, so having the date felt redundant. To create a new sensor using the relative_time function, youll need to edit your configuration.yaml.\nOnce youre editing your config file, add the following:\ntemplate: # Bird Time Last Seen - sensor: - name: \"Bird Last Seen\" state: \u003e {% set birdseen = (states('sensor.bird_date_seen')+' '+states('sensor.bird_time_seen')) %} {% set bird = relative_time(strptime(birdseen, '%Y-%m-%d %H:%M:%S')) %} {{ bird }} What this does is uses Home Assistants templating functionality and creates a new sensor called “Bird Last Seen”. The default sensor. name will be sensor.bird_last_seen.\nTo configure the state of that sensor, we first set a variable called birdseen. To this variable we are assigning the concatenated values of bird_date_seen, a single whitespace, and bird_time_seen. Were choosing this format because that is the format that relative_time returned before when we tried using it without a date.\nAs a quick experiment, take the templating code under the state: \u003e parameter above and throw it into Developer Tools \u003e Template. Do you get 126 years? Or something more realistic? If something more realistic, amazing!\nWere almost there! Heres what you should see in HomeAssistant if the sensor was created correctly. If youre new to templating for Home Assistant (or in general!) it would be helpful to read through a few of the docs that HomeAssistant provides.\nHomeAssistant Templating Docs Jinja2 Templating Engine Docs Note: Jinja2 is very popular and common. Learning it for home automation is worth it alone, but it may very well come in handy in other places too!\nData Card Yaml type: horizontal-stack cards: - type: custom:button-card entity: sensor.bird_time_seen show_state: true show_icon: true show_name: false icon: mdi:clock-outline color: darkgrey styles: card: - border: none - background: transparent - type: custom:button-card entity: sensor.bird_confidence show_state: true show_icon: true show_name: false icon: mdi:check-circle styles: card: - border: none - background: transparent icon: - color: | [[[ if (states['sensor.bird_confidence'].state \u003e 80 ) return \"green\"; return \"lightblue\"; ]]] - type: custom:button-card entity: sensor.bird_last_seen show_state: true show_icon: true show_name: false icon: mdi:timer-refresh-outline styles: card: - border: none - background: transparent icon: - color: | [[[ var y = states['sensor.bird_last_seen'].state; let x = y.slice(0, 2); var e = Number(x); if (e \u003c 5) return '#ff6969'; if (e \u003c 10) return '#ffdf87'; if (e \u003c 15) return '#d9d76f'; if (e \u003c 20) return '#fcc2ea'; else return '#ccccc8'; ]]] Weather Card This doesnt need a lot of explaining or instructions. It is just the standard weather card! Heres the YAML, none of the less, so you know what I toggled on/off. Im using Pirate Weather Integration as my data source.\nWeather Card type: custom:weather-card entity: weather.pirateweather forecast: false hourly_forecast: false name: null details: true current: true number_of_forecasts: '5' Description Card Finally, we reach the bottom of the dashboard: the description card. This one is also really straightforward. Were just using a standard markdown card and taking the description sensor we created using Wikipedias API and making that the main content of the card.\nOther than setting the theme, the only other small changes are removing the border and increasing from the default font size. Well use Thomas Lovens famous Card Mod for that.\nDescription Card type: markdown content: '{{ state_attr(''sensor.birdnet_wiki'',''description'')}}' theme: Catppuccin Mocha card_mod: style: | ha-card.type-markdown { border: none; } ha-markdown { font-size: 16px; } Conclusion And thats all there is to it! I say that flippantly, but I know that it can seem like theres a lot of setup. Everything I did here evolved out of other peoples projects and dashboards on Reddit or the invaluable HomeAssistant Community\nPlease feel free to reach out to me on Mastodon if you have any questions or get stuck anywhere!\nFull Dashboard YAML Full Dashboard YAML - theme: Catppuccin Macchiato title: BirdNet-Dashboard path: birdnet-dashboard icon: mdi:bird type: custom:vertical-layout badges: [] cards: - type: horizontal-stack cards: - type: custom:button-card entity: sensor.bird_common_name triggers_update: all show_name: false show_icon: false show_state: false show_label: false styles: card: - background: transparent - border: none - width: 215px - height: 175px custom_fields: picture: card: type: custom:button-card entity: camera.birdnet_flickr show_entity_picture: true show_name: false show_icon: false styles: card: - height: 100% - width: 100% - padding: 0px 15px 0px 15px - border-radius: 3px 3px 15px 3px - border: none - background: transparent - overflow: visible img_cell: - width: 180px - height: 160px - border-radius: 69% - border: 3px solid grey entity_picture: - width: 215px - height: 100% - type: vertical-stack cards: - type: custom:button-card entity: sensor.bird_common_name show_entity_picture: true show_state: true show_name: false show_icon: false styles: card: - background: transparent - border: none - margin-top: 35px - font-size: 25px - width: auto - type: custom:button-card entity: sensor.bird_science_name show_entity_picture: true show_state: true show_name: false show_icon: false styles: card: - background: transparent - border: black - width: auto - type: horizontal-stack cards: - type: custom:button-card entity: sensor.bird_time_seen show_state: true show_icon: true show_name: false icon: mdi:clock-outline color: darkgrey styles: card: - border: none - background: transparent - type: custom:button-card entity: sensor.bird_confidence show_state: true show_icon: true show_name: false icon: mdi:check-circle styles: card: - border: none - background: transparent icon: - color: | [[[ if (states['sensor.bird_confidence'].state \u003e 80 ) return \"green\"; return \"lightblue\"; ]]] - type: custom:button-card entity: sensor.bird_last_seen show_state: true show_icon: true show_name: false icon: mdi:timer-refresh-outline styles: card: - border: none - background: transparent icon: - color: | [[[ var y = states['sensor.bird_last_seen'].state; let x = y.slice(0, 2); var e = Number(x); if (e \u003c 5) return '#ff6969'; if (e \u003c 10) return '#ffdf87'; if (e \u003c 15) return '#d9d76f'; if (e \u003c 20) return '#fcc2ea'; else return '#ccccc8'; ]]] - type: custom:weather-card entity: weather.pirateweather forecast: false hourly_forecast: false name: null details: true current: true - type: markdown content: '{{ state_attr(''sensor.birdnet_wiki'',''description'')}}' theme: Catppuccin Mocha card_mod: style: | ha-card.type-markdown { border: none; } ha-markdown { font-size: 16px; } ",
"wordCount" : "1986",
"inLanguage": "en",
"image":"/birdnet-homeassistant-part2.png","datePublished": "2023-10-04T10:35:23-04:00",
"dateModified": "2023-10-04T10:35:23-04:00",
"author":{
"@type": "Person",
"name": "Me"
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "/posts/birdnet_homeassistant_part2.html"
},
"publisher": {
"@type": "Organization",
"name": "Norm-working Packets 💾",
"logo": {
"@type": "ImageObject",
"url": "/favicon.ico"
}
}
}
</script>
</head>
<body class=" dark" id="top">
<script>
if (localStorage.getItem("pref-theme") === "light") {
document.body.classList.remove('dark')
}
</script>
<header class="header">
<nav class="nav">
<div class="logo">
<a href="../" accesskey="h" title="Norm-working Packets 💾 (Alt + H)">Norm-working Packets 💾</a>
<div class="logo-switches">
<button id="theme-toggle" accesskey="t" title="(Alt + T)">
<svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
<svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</button>
<ul class="lang-switch"><li>|</li>
</ul>
</div>
</div>
<ul id="menu">
<li>
<a href="../posts.html" title="Posts">
<span>Posts</span>
</a>
</li>
</ul>
</nav>
</header>
<main class="main">
<article class="post-single">
<header class="post-header">
<div class="breadcrumbs"><a href="../">Home</a>&nbsp;»&nbsp;<a href="../posts.html">Posts</a></div>
<h1 class="post-title entry-hint-parent">
BirdNET-PI &amp; HomeAssistant: Part 2
</h1>
<div class="post-description">
A Follow up from the previous post, this tutorial takes all the sensors we created and loads them into a beautiful dashboard!
</div>
<div class="post-meta"><span title='2023-10-04 10:35:23 -0400 EDT'>October 4, 2023</span>&nbsp;·&nbsp;10 min&nbsp;·&nbsp;1986 words&nbsp;·&nbsp;Me
</div>
</header> <div class="toc">
<details >
<summary accesskey="c" title="(Alt + C)">
<span class="details">Table of Contents</span>
</summary>
<div class="inner"><nav id="TableOfContents">
<ul>
<li><a href="#checking-for-entities">Checking for Entities</a></li>
<li><a href="#dashboard-overview--dependencies">Dashboard Overview &amp; Dependencies</a></li>
<li><a href="#overview-card">Overview Card</a></li>
<li><a href="#data-card">Data Card</a>
<ul>
<li><a href="#creating-bird-last-seen-entity">Creating Bird Last Seen Entity</a></li>
</ul>
</li>
<li><a href="#weather-card">Weather Card</a></li>
<li><a href="#description-card">Description Card</a></li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#full-dashboard-yaml">Full Dashboard YAML</a></li>
</ul>
</nav>
</div>
</details>
</div>
<div class="post-content"><h2 id="checking-for-entities">Checking for Entities<a hidden class="anchor" aria-hidden="true" href="#checking-for-entities">#</a></h2>
<p>If you&rsquo;re following up on this from <a href="../posts/birdnet_homeassistant.html">my first post</a>, you&rsquo;ve already added your AppDaemon script and confirmed that the AppDaemon logs don&rsquo;t show any errors. Now is the true test if it&rsquo;s working: do you have the
new sensors in HomeAssistant?!</p>
<style type="text/css">
.box-shortcode {
padding: 1.6em;
padding-top: 1.4em;
line-height: 1.4em;
margin-top: 1em;
margin-bottom: 2em;
border-radius: 4px;
color: #444;
background: #f3ebe850;
}
.box-title {
margin: -18px -18px 12px;
padding: 4px 18px;
border-radius: 4px 4px 0 0;
font-weight: 700;
color: #fff;
background: #6ab0de;
}
.box-shortcode.warning .box-title {
background: #ff6b6b;
}
.box-shortcode.warning {
background: #ff6b6b4f;
}
.box-shortcode.info .box-title {
background: #0089e488;
}
.box-shortcode.info {
background: #0089e41c;
box-shadow: 3px 3px 5px #0089e410;
}
.box-shortcode.important .box-title {
background: #f7ec2c;
}
.box-shortcode.important {
background: #f7ec2c7d;
}
.box-shortcode.tip .box-title {
background: #a3ffa34d;
}
.box-shortcode.tip {
background: #a3ffa34d;
box-shadow: 3px 3px 5px #0089e410;
}
.icon-box {
display: inline-flex;
align-self: center;
margin-right: 8px;
}
.icon-box img,
.icon-box svg {
height: 1em;
width: 1em;
fill: currentColor;
}
.icon-box img,
.icon-box.baseline svg {
top: 0.125em;
position: relative;
}
.box-shortcode p {
margin-bottom: 0.6em;
}
.box-shortcode p:first-of-type {
display: inline;
}
.box-shortcode p:nth-of-type(2) {
margin-top: 0.6em;
}
.box-shortcode p:last-child {
margin-bottom: 0;
}
</style>
<svg width="0" height="0" display="none" xmlns="http://www.w3.org/2000/svg">
<symbol id="tip-box" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">
<path
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/>
</symbol>
<symbol id="important-box" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">
<path
d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/>
</symbol>
<symbol id="warning-box" viewBox="0 0 576 512" preserveAspectRatio="xMidYMid meet">
<path
d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/>
</symbol>
<symbol id="info-box" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">
<path
d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"/>
</symbol>
</svg><div class="box box-shortcode info" >
<span class="icon-box baseline">
<svg><use href="#info-box"></use></svg>
</span>
<p>The best way to do this is by just type <code>e</code> from any screen in the HomeAssistant UI! That will bring up a list of entities.
Start typing &ldquo;bird&rdquo; or &ldquo;birdnet&rdquo; and you should see the new entities listed there.</p>
</div>
<h2 id="dashboard-overview--dependencies">Dashboard Overview &amp; Dependencies<a hidden class="anchor" aria-hidden="true" href="#dashboard-overview--dependencies">#</a></h2>
<p>Now that we have the correct entities, lets take a look at what we&rsquo;re working with. Full disclosure that once I got this
working, I haven&rsquo;t really revisited it, refactored it, or made any improvements. I&rsquo;m sure you&rsquo;ll find ways to use less YAML,
but I wanted to get this out there sooner than later!</p>
<p><img loading="lazy" src="../posts/img/birdnet-homeassistant-dash-full.png" alt="HomeAssistant BirdNet-Pi Dashboard - Full View" />
</p>
<p>I&rsquo;ve included the code for all the cards at the bottom of this post. You can find them <a href="../posts/birdnet_homeassistant_part2.html#dashboard-yaml">here</a>.
This dashboard is pretty simple, it brings in almost all of the sensors
we created in the first post and organizes them in an as-pleasant-as-possible view. I&rsquo;m definitely not a designer, so some of
the colors could be worked on&hellip;</p>
<p>Sensors in the dashboard:</p>
<ul>
<li><a href="../posts/birdnet_homeassistant_part2.html#overview-card">Overview Card:</a>
<ul>
<li>sensor.bird_common_name (only used to generate the picture)</li>
<li>camera.birdnet_flickr</li>
<li>sensor.bird_common_name</li>
<li>sensor.bird_science_name</li>
</ul>
</li>
<li>Data Card:
<ul>
<li>sensor.bird_time_seen</li>
<li>sensor.bird_confidence</li>
<li>sensor.bird_last_seen</li>
</ul>
</li>
<li>Weather Card:
<ul>
<li>weather.pirateweather</li>
</ul>
</li>
<li>Description Card:
<ul>
<li>sensor.birdnet_wiki</li>
</ul>
</li>
</ul>
<p>There are also two HomeAssistant dashboard dependencies that you&rsquo;ll need for this dashboard:</p>
<ul>
<li><a href="https://github.com/bramkragten/weather-card">Custom Weather Card</a></li>
<li><a href="https://github.com/custom-cards/button-card">Custom Button Card</a></li>
<li><a href="https://github.com/thomasloven/lovelace-card-mod">Custom Card Mod</a></li>
</ul>
<p>Now that we&rsquo;ve got that squared away, let&rsquo;s jump into each card.</p>
<h2 id="overview-card">Overview Card<a hidden class="anchor" aria-hidden="true" href="#overview-card">#</a></h2>
<p><img loading="lazy" src="../posts/img/birdnet-homeassistant-overview-card.png" alt="Overview Card" />
</p>
<p>You&rsquo;ll notice from the few dependencies listed above, that I use this button card. <strong>A lot.</strong>
<a href="https://github.com/RomRider">RomRider</a> did a fantastic job of adding in a ton of flexibility into the card. For the overview
card, we&rsquo;re taking one of the entities, in this case, <code>bird_common_name</code> and attaching the Flickr picture/sensor to it. Then,
on the right, I&rsquo;m displaying the name and common name. Here&rsquo;s the overview card&rsquo;s yaml.</p>
<p>The tricky or tedious part of this card is making sure most of the card&rsquo;s attributes (icon, name, state, label) are set to
false. Another option for the Common and Scientific name on the right is to use a markdown card. I couldn&rsquo;t get the
formatting just right when using that card and some grid-card tricks, so I opted to reuse the super flexible button-card.</p>
<p>Pay attention to the styles for the image (lines 24-40). Those are what keep the border around the image along with the image
a certain height and width so that it looks proportional on the page.</p>
<p>One additional thing I have been toying with but hadn&rsquo;t finalized was messing with <code>[img_cell][border]</code>. By adding some
javascript in that section (see other cards), you could change the color of the border based on another parameter. Perhaps
you look at the state of <code>sensor.bird_common_name</code> and if there is the name of a color in there, that&rsquo;s the border&rsquo;s color.
Feel free to get crazy and creative with this!</p>
<style>
details summary {
min-width: 200px;
font-weight: 600;
cursor: pointer;
}
details summary > * {
display: inline;
}
details {
margin: 1em;
border-radius: 5px;
padding: 1em;
overflow: hidden;
box-shadow: 0 .1rem 1rem -.5rem rgba(0,0,0,.4);
}
summary {
padding: 0 1rem .3em 1.2rem;
display: block;
position: relative;
cursor: pointer;
}
summary:before {
content: '>';
position: absolute;
top: .1rem;
left: 0.1rem;
transform: rotate(0);
transition: .3s transform ease;
}
details[open] > summary:before {
transform: rotate(180deg);
content: '-';
}
details summary::-webkit-details-marker {
display:none;
}
</style><details><summary>Overview Card YAML</summary>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">type</span>: <span style="color:#ae81ff">horizontal-stack</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_common_name</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">triggers_update</span>: <span style="color:#ae81ff">all</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_label</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">215px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">175px</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">custom_fields</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">picture</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">camera.birdnet_flickr</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_entity_picture</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">100</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">100</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">padding</span>: <span style="color:#ae81ff">0px 15px 0px 15px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border-radius</span>: <span style="color:#ae81ff">3px 3px 15px 3px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">overflow</span>: <span style="color:#ae81ff">visible</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">img_cell</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">180px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">160px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border-radius</span>: <span style="color:#ae81ff">69</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">3px solid grey</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity_picture</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">215px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">100</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">vertical-stack</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_common_name</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_entity_picture</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">margin-top</span>: <span style="color:#ae81ff">35px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">font-size</span>: <span style="color:#ae81ff">25px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">auto</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_science_name</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_entity_picture</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">black</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">auto</span>
</span></span></code></pre></div>
</details>
<h2 id="data-card">Data Card<a hidden class="anchor" aria-hidden="true" href="#data-card">#</a></h2>
<p><img loading="lazy" src="../posts/img/birdnet-homeassistant-data-card.png" alt="Data Card" />
</p>
<p>This card is fairly straight forward in that it&rsquo;s showing 3 key data points: the time of detection, detection confidence,
how long ago it was seen. This could be fairly redundant since we already have the time of detection, but when you&rsquo;re just
quickly glancing at the dashboard, minutes ago is much faster brain processing than comparing the timestamp and the current
time.</p>
<p>You&rsquo;ve likely picked up by now that in the previous post, we never sent a payload to create the <code>sensor.bird_last_seen</code>
entity. Here&rsquo;s how you can do it.</p>
<h3 id="creating-bird-last-seen-entity">Creating Bird Last Seen Entity<a hidden class="anchor" aria-hidden="true" href="#creating-bird-last-seen-entity">#</a></h3>
<p>When I first set out to create this sensor, I was messing with jinja templates for timestamp, datetime, strptime, and more.
Here are a few code blocks I saved in my notes in case I went too far down the wrong path. Here are a few of them.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-jinja" data-lang="jinja"><span style="display:flex;"><span><span style="color:#75715e">{{</span> now<span style="color:#f92672">()</span> <span style="color:#f92672">-</span> state_attr<span style="color:#f92672">(</span>sensor.bird_time_seen<span style="color:#f92672">,</span> <span style="color:#e6db74">&#39;last_triggered&#39;</span><span style="color:#f92672">)</span> <span style="color:#f92672">&gt;</span> timedelta<span style="color:#f92672">(</span>hours<span style="color:#f92672">=</span><span style="color:#ae81ff">24</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span></code></pre></div><p>or:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-jinja" data-lang="jinja"><span style="display:flex;"><span><span style="color:#75715e">{%</span> <span style="color:#66d9ef">set</span> bird <span style="color:#f92672">=</span> strptime<span style="color:#f92672">(</span>states<span style="color:#f92672">(</span><span style="color:#e6db74">&#39;sensor.bird_time_seen&#39;</span><span style="color:#f92672">),</span> <span style="color:#e6db74">&#34;%H:%M:%S&#34;</span><span style="color:#f92672">)</span> <span style="color:#75715e">%}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> relative_time<span style="color:#f92672">(</span>bird<span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span></code></pre></div><p>The thing is, HomeAssistant has already implemented this really neat feature for calculating time, especially from when
something was last updated. This function is called <code>relative_time</code>. Having something like this allows you set automations
to run after a specific amount of time has passed since the last time a sensor or entity was updated.</p>
<div class="box box-shortcode tip" >
<span class="icon-box baseline">
<svg><use href="#tip-box"></use></svg>
</span>
<p>An idea! 💡 For our specific use case, you could set up an automation that sends you a notification if no birds have been detected for
over 30 minutes. Of course, we&rsquo;ll set parameters like not to notify you at night or during the winter months.</p>
</div>
<p>The issue I faced with relative time has to do with the sensors I created from my AppDaemon script. Relative time expects
a date <em>and</em> time. I was only passing the time. In Home Assitant if you use the Developer Tools &gt; Template to test relative
time out on the <code>sensor.bird_time_seen</code> sensor, you&rsquo;ll get a result of 126 years&hellip; That&rsquo;s because without a date, Home
Assistant defaults the date to <code>1900-01-01</code>. The full relative_time return is <code>1900-01-01 15:15:15</code>.</p>
<p>We could go back and set the sensors to include both date and time, but I prefer them separate so that I can use them in
different places. For this dashboard, the day is always today, so having the date felt redundant. To create a new sensor
using the <code>relative_time</code> function, you&rsquo;ll need to edit your <code>configuration.yaml</code>.</p>
<p>Once you&rsquo;re editing your config file, add the following:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">template</span>:
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Bird Time Last Seen</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">sensor</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;Bird Last Seen&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">state</span>: &gt;<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> {% set birdseen = (states(&#39;sensor.bird_date_seen&#39;)+&#39; &#39;+states(&#39;sensor.bird_time_seen&#39;)) %}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> {% set bird = relative_time(strptime(birdseen, &#39;%Y-%m-%d %H:%M:%S&#39;)) %}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> {{ bird }}</span>
</span></span></code></pre></div><p>What this does is uses Home Assistant&rsquo;s templating functionality and creates a new sensor called &ldquo;Bird Last Seen&rdquo;. The
default <code>sensor.</code> name will be <code>sensor.bird_last_seen</code>.</p>
<p>To configure the state of that sensor, we first set a variable called <code>birdseen</code>. To this variable we are assigning the
concatenated values of <code>bird_date_seen</code>, a single whitespace, and <code>bird_time_seen</code>. We&rsquo;re choosing this format because that
is the format that <code>relative_time</code> returned before when we tried using it without a date.</p>
<p>As a quick experiment, take the templating code under the <code>state: &gt;</code> parameter above and throw it into Developer Tools &gt;
Template. Do you get 126 years? Or something more realistic? If something more realistic, amazing!</p>
<p>We&rsquo;re almost there! Here&rsquo;s what you should see in HomeAssistant if the sensor was created correctly.
<img loading="lazy" src="../posts/img/birdnet-homeassistant-birdseen-sensor.png" alt="Bird Last Seen Entity" />
</p>
<div class="box box-shortcode info" >
<span class="icon-box baseline">
<svg><use href="#info-box"></use></svg>
</span>
<p>If you&rsquo;re new to templating for Home Assistant (or in general!) it would be helpful to read through a few of the docs that
HomeAssistant provides.</p>
<ul>
<li><a href="https://www.home-assistant.io/docs/configuration/templating/">HomeAssistant Templating Docs</a></li>
<li><a href="https://palletsprojects.com/p/jinja">Jinja2 Templating Engine Docs</a></li>
</ul>
<p><em>Note: Jinja2 is very popular and common. Learning it for home automation is worth it alone, but it may very well come in
handy in other places too!</em></p>
</div>
<details><summary>Data Card Yaml</summary>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">type</span>: <span style="color:#ae81ff">horizontal-stack</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_time_seen</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:clock-outline</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">color</span>: <span style="color:#ae81ff">darkgrey</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_confidence</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:check-circle</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">color</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> [[[
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (states[&#39;sensor.bird_confidence&#39;].state &gt; 80 )
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> return &#34;green&#34;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> return &#34;lightblue&#34;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ]]]</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_last_seen</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:timer-refresh-outline</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">color</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> [[[
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> var y = states[&#39;sensor.bird_last_seen&#39;].state;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> let x = y.slice(0, 2);
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> var e = Number(x);
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 5) return &#39;#ff6969&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 10) return &#39;#ffdf87&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 15) return &#39;#d9d76f&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 20) return &#39;#fcc2ea&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> else return &#39;#ccccc8&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ]]]</span>
</span></span></code></pre></div>
</details>
<h2 id="weather-card">Weather Card<a hidden class="anchor" aria-hidden="true" href="#weather-card">#</a></h2>
<p><img loading="lazy" src="../posts/img/birdnet-homeassistant-weather-card.png" alt="Weather Card" />
</p>
<p>This doesn&rsquo;t need a lot of explaining or instructions. It is just the standard weather card! Here&rsquo;s the YAML, none of the
less, so you know what I toggled on/off. I&rsquo;m using <a href="https://pirateweather.net/en/latest/">Pirate Weather Integration</a> as my
data source.</p>
<details><summary>Weather Card</summary>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:weather-card</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">entity</span>: <span style="color:#ae81ff">weather.pirateweather</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">forecast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">hourly_forecast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">name</span>: <span style="color:#66d9ef">null</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">details</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">current</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">number_of_forecasts</span>: <span style="color:#e6db74">&#39;5&#39;</span>
</span></span></code></pre></div>
</details>
<h2 id="description-card">Description Card<a hidden class="anchor" aria-hidden="true" href="#description-card">#</a></h2>
<p>Finally, we reach the bottom of the dashboard: the description card. This one is also really straightforward. We&rsquo;re just
using a <a href="https://www.home-assistant.io/dashboards/markdown/">standard markdown card</a> and taking the description sensor we
created using Wikipedia&rsquo;s API and making that the main content of the card.</p>
<p><img loading="lazy" src="../posts/img/birdnet-homeassistant-description-card.png" alt="Bird Description Card" />
</p>
<p>Other than setting the theme, the only other small changes are removing the border and increasing from the default font size.
We&rsquo;ll use <a href="https://github.com/thomasloven">Thomas Loven&rsquo;s</a> famous Card Mod for that.</p>
<details><summary>Description Card</summary>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">type</span>: <span style="color:#ae81ff">markdown</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">content</span>: <span style="color:#e6db74">&#39;{{ state_attr(&#39;&#39;sensor.birdnet_wiki&#39;&#39;,&#39;&#39;description&#39;&#39;)}}&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">theme</span>: <span style="color:#ae81ff">Catppuccin Mocha</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">card_mod</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">style</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ha-card.type-markdown {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> border: none;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ha-markdown {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> font-size: 16px;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }</span>
</span></span></code></pre></div>
</details>
<h2 id="conclusion">Conclusion<a hidden class="anchor" aria-hidden="true" href="#conclusion">#</a></h2>
<p>And that&rsquo;s all there is to it! I say that flippantly, but I know that it can seem like there&rsquo;s a lot of setup. Everything I
did here evolved out of other people&rsquo;s projects and dashboards on <a href="www.reddit.com/r/homeassistant">Reddit</a> or the invaluable
<a href="https://community.home-assistant.io/">HomeAssistant Community</a></p>
<p>Please feel free to reach out to me on <a href="www.fosstodon.org/@notnorm">Mastodon</a> if you have any questions or get stuck
anywhere!</p>
<h2 id="full-dashboard-yaml">Full Dashboard YAML<a hidden class="anchor" aria-hidden="true" href="#full-dashboard-yaml">#</a></h2>
<details><summary>Full Dashboard YAML</summary>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>- <span style="color:#f92672">theme</span>: <span style="color:#ae81ff">Catppuccin Macchiato</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">title</span>: <span style="color:#ae81ff">BirdNet-Dashboard</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">path</span>: <span style="color:#ae81ff">birdnet-dashboard</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:bird</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:vertical-layout</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">badges</span>: []
</span></span><span style="display:flex;"><span> <span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">horizontal-stack</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_common_name</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">triggers_update</span>: <span style="color:#ae81ff">all</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_label</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">215px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">175px</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">custom_fields</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">picture</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">camera.birdnet_flickr</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_entity_picture</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">100</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">100</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">padding</span>: <span style="color:#ae81ff">0px 15px 0px 15px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border-radius</span>: <span style="color:#ae81ff">3px 3px 15px 3px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">overflow</span>: <span style="color:#ae81ff">visible</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">img_cell</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">180px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">160px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border-radius</span>: <span style="color:#ae81ff">69</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">3px solid grey</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity_picture</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">215px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">height</span>: <span style="color:#ae81ff">100</span><span style="color:#ae81ff">%</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">vertical-stack</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_common_name</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_entity_picture</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">margin-top</span>: <span style="color:#ae81ff">35px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">font-size</span>: <span style="color:#ae81ff">25px</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">auto</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_science_name</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_entity_picture</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">black</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">width</span>: <span style="color:#ae81ff">auto</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">horizontal-stack</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">cards</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_time_seen</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:clock-outline</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">color</span>: <span style="color:#ae81ff">darkgrey</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_confidence</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:check-circle</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">color</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> [[[
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (states[&#39;sensor.bird_confidence&#39;].state &gt; 80 )
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> return &#34;green&#34;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> return &#34;lightblue&#34;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ]]]</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:button-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">sensor.bird_last_seen</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_icon</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">show_name</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>: <span style="color:#ae81ff">mdi:timer-refresh-outline</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">styles</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">border</span>: <span style="color:#ae81ff">none</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">background</span>: <span style="color:#ae81ff">transparent</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">icon</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">color</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> [[[
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> var y = states[&#39;sensor.bird_last_seen&#39;].state;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> let x = y.slice(0, 2);
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> var e = Number(x);
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 5) return &#39;#ff6969&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 10) return &#39;#ffdf87&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 15) return &#39;#d9d76f&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> if (e &lt; 20) return &#39;#fcc2ea&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> else return &#39;#ccccc8&#39;;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ]]]</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">custom:weather-card</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">entity</span>: <span style="color:#ae81ff">weather.pirateweather</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">forecast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">hourly_forecast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#66d9ef">null</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">details</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">current</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">type</span>: <span style="color:#ae81ff">markdown</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">content</span>: <span style="color:#e6db74">&#39;{{ state_attr(&#39;&#39;sensor.birdnet_wiki&#39;&#39;,&#39;&#39;description&#39;&#39;)}}&#39;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">theme</span>: <span style="color:#ae81ff">Catppuccin Mocha</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">card_mod</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">style</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ha-card.type-markdown {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> border: none;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> ha-markdown {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> font-size: 16px;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }</span>
</span></span></code></pre></div>
</details>
<style>
.box-shortcode {
color: #e8e8e8;
border: none;
}
.post-content img {
margin: auto
}
</style>
</div>
<footer class="post-footer">
<ul class="post-tags">
<li><a href="../tags/homeassistant.html">Homeassistant</a></li>
<li><a href="../tags/diy.html">Diy</a></li>
<li><a href="../tags/selfhosted.html">Selfhosted</a></li>
</ul>
<nav class="paginav">
<a class="prev" href="../posts/medicine_indicator_light.html">
<span class="title">« Prev</span>
<br>
<span>ESP8266 Medicine Indicator Light</span>
</a>
<a class="next" href="../posts/birdnet_homeassistant.html">
<span class="title">Next »</span>
<br>
<span>Creating a BirdNetPi Dashboard in HomeAssistant - Part 1</span>
</a>
</nav>
<ul class="share-buttons">
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on x"
href="https://x.com/intent/tweet/?text=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202&amp;url=%2fposts%2fbirdnet_homeassistant_part2.html&amp;hashtags=homeassistant%2cdiy%2cselfhosted">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M512 62.554 L 512 449.446 C 512 483.97 483.97 512 449.446 512 L 62.554 512 C 28.03 512 0 483.97 0 449.446 L 0 62.554 C 0 28.03 28.029 0 62.554 0 L 449.446 0 C 483.971 0 512 28.03 512 62.554 Z M 269.951 190.75 L 182.567 75.216 L 56 75.216 L 207.216 272.95 L 63.9 436.783 L 125.266 436.783 L 235.9 310.383 L 332.567 436.783 L 456 436.783 L 298.367 228.367 L 432.367 75.216 L 371.033 75.216 Z M 127.633 110 L 164.101 110 L 383.481 400.065 L 349.5 400.065 Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on linkedin"
href="https://www.linkedin.com/shareArticle?mini=true&amp;url=%2fposts%2fbirdnet_homeassistant_part2.html&amp;title=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202&amp;summary=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202&amp;source=%2fposts%2fbirdnet_homeassistant_part2.html">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-288.985,423.278l0,-225.717l-75.04,0l0,225.717l75.04,0Zm270.539,0l0,-129.439c0,-69.333 -37.018,-101.586 -86.381,-101.586c-39.804,0 -57.634,21.891 -67.617,37.266l0,-31.958l-75.021,0c0.995,21.181 0,225.717 0,225.717l75.02,0l0,-126.056c0,-6.748 0.486,-13.492 2.474,-18.315c5.414,-13.475 17.767,-27.434 38.494,-27.434c27.135,0 38.007,20.707 38.007,51.037l0,120.768l75.024,0Zm-307.552,-334.556c-25.674,0 -42.448,16.879 -42.448,39.002c0,21.658 16.264,39.002 41.455,39.002l0.484,0c26.165,0 42.452,-17.344 42.452,-39.002c-0.485,-22.092 -16.241,-38.954 -41.943,-39.002Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on reddit"
href="https://reddit.com/submit?url=%2fposts%2fbirdnet_homeassistant_part2.html&title=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-3.446,265.638c0,-22.964 -18.616,-41.58 -41.58,-41.58c-11.211,0 -21.361,4.457 -28.841,11.666c-28.424,-20.508 -67.586,-33.757 -111.204,-35.278l18.941,-89.121l61.884,13.157c0.756,15.734 13.642,28.29 29.56,28.29c16.407,0 29.706,-13.299 29.706,-29.701c0,-16.403 -13.299,-29.702 -29.706,-29.702c-11.666,0 -21.657,6.792 -26.515,16.578l-69.105,-14.69c-1.922,-0.418 -3.939,-0.042 -5.585,1.036c-1.658,1.073 -2.811,2.761 -3.224,4.686l-21.152,99.438c-44.258,1.228 -84.046,14.494 -112.837,35.232c-7.468,-7.164 -17.589,-11.591 -28.757,-11.591c-22.965,0 -41.585,18.616 -41.585,41.58c0,16.896 10.095,31.41 24.568,37.918c-0.639,4.135 -0.99,8.328 -0.99,12.576c0,63.977 74.469,115.836 166.33,115.836c91.861,0 166.334,-51.859 166.334,-115.836c0,-4.218 -0.347,-8.387 -0.977,-12.493c14.564,-6.47 24.735,-21.034 24.735,-38.001Zm-119.474,108.193c-20.27,20.241 -59.115,21.816 -70.534,21.816c-11.428,0 -50.277,-1.575 -70.522,-21.82c-3.007,-3.008 -3.007,-7.882 0,-10.889c3.003,-2.999 7.882,-3.003 10.885,0c12.777,12.781 40.11,17.317 59.637,17.317c19.522,0 46.86,-4.536 59.657,-17.321c3.016,-2.999 7.886,-2.995 10.885,0.008c3.008,3.011 3.003,7.882 -0.008,10.889Zm-5.23,-48.781c-16.373,0 -29.701,-13.324 -29.701,-29.698c0,-16.381 13.328,-29.714 29.701,-29.714c16.378,0 29.706,13.333 29.706,29.714c0,16.374 -13.328,29.698 -29.706,29.698Zm-160.386,-29.702c0,-16.381 13.328,-29.71 29.714,-29.71c16.369,0 29.689,13.329 29.689,29.71c0,16.373 -13.32,29.693 -29.689,29.693c-16.386,0 -29.714,-13.32 -29.714,-29.693Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on facebook"
href="https://facebook.com/sharer/sharer.php?u=%2fposts%2fbirdnet_homeassistant_part2.html">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-106.468,0l0,-192.915l66.6,0l12.672,-82.621l-79.272,0l0,-53.617c0,-22.603 11.073,-44.636 46.58,-44.636l36.042,0l0,-70.34c0,0 -32.71,-5.582 -63.982,-5.582c-65.288,0 -107.96,39.569 -107.96,111.204l0,62.971l-72.573,0l0,82.621l72.573,0l0,192.915l-191.104,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on whatsapp"
href="https://api.whatsapp.com/send?text=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202%20-%20%2fposts%2fbirdnet_homeassistant_part2.html">
<svg version="1.1" viewBox="0 0 512 512" xml:space="preserve" height="30px" width="30px" fill="currentColor">
<path
d="M449.446,0c34.525,0 62.554,28.03 62.554,62.554l0,386.892c0,34.524 -28.03,62.554 -62.554,62.554l-386.892,0c-34.524,0 -62.554,-28.03 -62.554,-62.554l0,-386.892c0,-34.524 28.029,-62.554 62.554,-62.554l386.892,0Zm-58.673,127.703c-33.842,-33.881 -78.847,-52.548 -126.798,-52.568c-98.799,0 -179.21,80.405 -179.249,179.234c-0.013,31.593 8.241,62.428 23.927,89.612l-25.429,92.884l95.021,-24.925c26.181,14.28 55.659,21.807 85.658,21.816l0.074,0c98.789,0 179.206,-80.413 179.247,-179.243c0.018,-47.895 -18.61,-92.93 -52.451,-126.81Zm-126.797,275.782l-0.06,0c-26.734,-0.01 -52.954,-7.193 -75.828,-20.767l-5.441,-3.229l-56.386,14.792l15.05,-54.977l-3.542,-5.637c-14.913,-23.72 -22.791,-51.136 -22.779,-79.287c0.033,-82.142 66.867,-148.971 149.046,-148.971c39.793,0.014 77.199,15.531 105.329,43.692c28.128,28.16 43.609,65.592 43.594,105.4c-0.034,82.149 -66.866,148.983 -148.983,148.984Zm81.721,-111.581c-4.479,-2.242 -26.499,-13.075 -30.604,-14.571c-4.105,-1.495 -7.091,-2.241 -10.077,2.241c-2.986,4.483 -11.569,14.572 -14.182,17.562c-2.612,2.988 -5.225,3.364 -9.703,1.12c-4.479,-2.241 -18.91,-6.97 -36.017,-22.23c-13.314,-11.876 -22.304,-26.542 -24.916,-31.026c-2.612,-4.484 -0.279,-6.908 1.963,-9.14c2.016,-2.007 4.48,-5.232 6.719,-7.847c2.24,-2.615 2.986,-4.484 4.479,-7.472c1.493,-2.99 0.747,-5.604 -0.374,-7.846c-1.119,-2.241 -10.077,-24.288 -13.809,-33.256c-3.635,-8.733 -7.327,-7.55 -10.077,-7.688c-2.609,-0.13 -5.598,-0.158 -8.583,-0.158c-2.986,0 -7.839,1.121 -11.944,5.604c-4.105,4.484 -15.675,15.32 -15.675,37.364c0,22.046 16.048,43.342 18.287,46.332c2.24,2.99 31.582,48.227 76.511,67.627c10.685,4.615 19.028,7.371 25.533,9.434c10.728,3.41 20.492,2.929 28.209,1.775c8.605,-1.285 26.499,-10.833 30.231,-21.295c3.732,-10.464 3.732,-19.431 2.612,-21.298c-1.119,-1.869 -4.105,-2.99 -8.583,-5.232Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on telegram"
href="https://telegram.me/share/url?text=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202&amp;url=%2fposts%2fbirdnet_homeassistant_part2.html">
<svg version="1.1" xml:space="preserve" viewBox="2 2 28 28" height="30px" width="30px" fill="currentColor">
<path
d="M26.49,29.86H5.5a3.37,3.37,0,0,1-2.47-1,3.35,3.35,0,0,1-1-2.47V5.48A3.36,3.36,0,0,1,3,3,3.37,3.37,0,0,1,5.5,2h21A3.38,3.38,0,0,1,29,3a3.36,3.36,0,0,1,1,2.46V26.37a3.35,3.35,0,0,1-1,2.47A3.38,3.38,0,0,1,26.49,29.86Zm-5.38-6.71a.79.79,0,0,0,.85-.66L24.73,9.24a.55.55,0,0,0-.18-.46.62.62,0,0,0-.41-.17q-.08,0-16.53,6.11a.59.59,0,0,0-.41.59.57.57,0,0,0,.43.52l4,1.24,1.61,4.83a.62.62,0,0,0,.63.43.56.56,0,0,0,.4-.17L16.54,20l4.09,3A.9.9,0,0,0,21.11,23.15ZM13.8,20.71l-1.21-4q8.72-5.55,8.78-5.55c.15,0,.23,0,.23.16a.18.18,0,0,1,0,.06s-2.51,2.3-7.52,6.8Z" />
</svg>
</a>
</li>
<li>
<a target="_blank" rel="noopener noreferrer" aria-label="share BirdNET-PI &amp; HomeAssistant: Part 2 on ycombinator"
href="https://news.ycombinator.com/submitlink?t=BirdNET-PI%20%26%20HomeAssistant%3a%20Part%202&u=%2fposts%2fbirdnet_homeassistant_part2.html">
<svg version="1.1" xml:space="preserve" width="30px" height="30px" viewBox="0 0 512 512" fill="currentColor"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<path
d="M449.446 0C483.971 0 512 28.03 512 62.554L512 449.446C512 483.97 483.97 512 449.446 512L62.554 512C28.03 512 0 483.97 0 449.446L0 62.554C0 28.03 28.029 0 62.554 0L449.446 0ZM183.8767 87.9921H121.8427L230.6673 292.4508V424.0079H281.3328V292.4508L390.1575 87.9921H328.1233L256 238.2489z" />
</svg>
</a>
</li>
</ul>
</footer>
</article>
</main>
<footer class="footer">
<span>&copy; 2024 <a href="../">Norm-working Packets 💾</a></span>
<span>
Powered by
<a href="https://gohugo.io/" rel="noopener noreferrer" target="_blank">Hugo</a> &
<a href="https://github.com/adityatelange/hugo-PaperMod/" rel="noopener" target="_blank">PaperMod</a>
</span>
</footer>
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
<path d="M12 6H0l6-6z" />
</svg>
</a>
<script>
let menu = document.getElementById('menu')
if (menu) {
menu.scrollLeft = localStorage.getItem("menu-scroll-position");
menu.onscroll = function () {
localStorage.setItem("menu-scroll-position", menu.scrollLeft);
}
}
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener("click", function (e) {
e.preventDefault();
var id = this.getAttribute("href").substr(1);
if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
behavior: "smooth"
});
} else {
document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
}
if (id === "top") {
history.replaceState(null, null, " ");
} else {
history.pushState(null, null, `#${id}`);
}
});
});
</script>
<script>
var mybutton = document.getElementById("top-link");
window.onscroll = function () {
if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
mybutton.style.visibility = "visible";
mybutton.style.opacity = "1";
} else {
mybutton.style.visibility = "hidden";
mybutton.style.opacity = "0";
}
};
</script>
<script>
document.getElementById("theme-toggle").addEventListener("click", () => {
if (document.body.className.includes("dark")) {
document.body.classList.remove('dark');
localStorage.setItem("pref-theme", 'light');
} else {
document.body.classList.add('dark');
localStorage.setItem("pref-theme", 'dark');
}
})
</script>
<script>
document.querySelectorAll('pre > code').forEach((codeblock) => {
const container = codeblock.parentNode.parentNode;
const copybutton = document.createElement('button');
copybutton.classList.add('copy-code');
copybutton.innerHTML = 'copy';
function copyingDone() {
copybutton.innerHTML = 'copied!';
setTimeout(() => {
copybutton.innerHTML = 'copy';
}, 2000);
}
copybutton.addEventListener('click', (cb) => {
if ('clipboard' in navigator) {
navigator.clipboard.writeText(codeblock.textContent);
copyingDone();
return;
}
const range = document.createRange();
range.selectNodeContents(codeblock);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
try {
document.execCommand('copy');
copyingDone();
} catch (e) { };
selection.removeRange(range);
});
if (container.classList.contains("highlight")) {
container.appendChild(copybutton);
} else if (container.parentNode.firstChild == container) {
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
} else {
codeblock.parentNode.appendChild(copybutton);
}
});
</script>
</body>
</html>