Bigger overhaul. Updated the Part 2 Home Assistant Birdnet post. Added some menus and tags.
This commit is contained in:
@ -1,11 +1,11 @@
|
||||
---
|
||||
title: 'Creating a BirdNetPi Dashboard in HomeAssistant - Part 1'
|
||||
date: 2023-09-25T12:51:55-04:00
|
||||
date: 2023-09-30T11:21:55-04:00
|
||||
tags: ["homeassistant", "python", "diy"]
|
||||
author: "Me"
|
||||
showToc: true
|
||||
TocOpen: false
|
||||
draft: true
|
||||
draft: false
|
||||
hidemeta: false
|
||||
description: 'Learn how to take BirdNET-Pi Detections to create and display entities in HomeAssistant.'
|
||||
disableHLJS: true # to disable highlightjs
|
||||
|
||||
537
content/posts/birdnet_homeassistant_part2.md
Normal file
537
content/posts/birdnet_homeassistant_part2.md
Normal file
@ -0,0 +1,537 @@
|
||||
---
|
||||
title: 'BirdNET-PI & HomeAssistant: Part 2'
|
||||
date: 2023-10-04T10:35:23-04:00
|
||||
tags: ["homeassistant", "diy", "selfhosted"]
|
||||
categories: ["Tutorial"]
|
||||
author: "Me"
|
||||
showToc: true
|
||||
TocOpen: false
|
||||
draft: false
|
||||
hidemeta: false
|
||||
description: 'A Follow up from the previous post, this tutorial takes all the sensors we created and loads them into a beautiful dashboard!'
|
||||
disableHLJS: true
|
||||
disableShare: false
|
||||
disableHLJS: false
|
||||
hideSummary: false
|
||||
searchHidden: true
|
||||
ShowReadingTime: true
|
||||
ShowBreadCrumbs: true
|
||||
ShowPostNavLinks: true
|
||||
ShowWordCount: true
|
||||
ShowRssButtonInSectionTermList: true
|
||||
UseHugoToc: true
|
||||
ShowBreadCrumbs: true
|
||||
cover:
|
||||
image: "birdnet-homeassistant-part2.png"
|
||||
alt: "Part 2 of my foray into HomeAssistant dashboard featuring BirdNET-Pi Sensors"
|
||||
caption: "Part 2 of my foray into HomeAssistant dashboard featuring BirdNET-Pi Sensors"
|
||||
relative: false
|
||||
hidden: true
|
||||
---
|
||||
|
||||
## Checking for Entities
|
||||
|
||||
If you're following up on this from [my first post]({{< ref "posts/birdnet_homeassistant.md" >}}), you've already added your AppDaemon script and confirmed that the AppDaemon logs don't show any errors. Now is the true test if it's working: do you have the
|
||||
new sensors in HomeAssistant?!
|
||||
|
||||
{{< box info >}}
|
||||
The 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.
|
||||
{{< /box >}}
|
||||
|
||||
## Dashboard Overview & Dependencies
|
||||
|
||||
Now that we have the correct entities, lets take a look at what we're working with. Full disclosure that once I got this
|
||||
working, I haven't really revisited it, refactored it, or made any improvements. I'm sure you'll find ways to use less YAML,
|
||||
but I wanted to get this out there sooner than later!
|
||||
|
||||

|
||||
|
||||
I've include the code for all the cards at the bottom of this post. You can find them [here]{{< ref
|
||||
"birdnet_homeassistant_part2.md#dashboard-yaml" >}}. 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'm definitely not a designer, so some of
|
||||
the colors could be worked on...
|
||||
|
||||
Sensors in the dashboard:
|
||||
|
||||
* [Overview Card:]({{< ref "birdnet_homeassistant_part2#overview-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 you'll need for this dashboard:
|
||||
|
||||
* [Custom Weather Card](https://github.com/bramkragten/weather-card)
|
||||
* [Custom Button Card](https://github.com/custom-cards/button-card)
|
||||
* [Custom Card Mod](https://github.com/thomasloven/lovelace-card-mod)
|
||||
|
||||
Now that we've got that squared away, let's jump into each card.
|
||||
|
||||
## Overview Card
|
||||
|
||||

|
||||
|
||||
You'll notice from the few dependencies listed above, that I use this button card. **A lot.**
|
||||
[RomRider](https://github.com/RomRider) did a fantastic job of adding in a ton of flexibility into the card. For the overview
|
||||
card, we're taking one of the entities, in this case, `bird_common_name` and attaching the Flickr picture/sensor to it. Then,
|
||||
on the right, I'm displaying the name and common name. Here's the overview card's yaml.
|
||||
|
||||
The tricky or tedious part of this card is making sure most of the card'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'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.
|
||||
|
||||
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.
|
||||
|
||||
One additional thing I have been toying with but hadn't 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, that's the border's color.
|
||||
Feel free to get crazy and creative with this!
|
||||
|
||||
{{< details "Overview Card YAML" >}}
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
{{< /details>}}
|
||||
|
||||
## Data Card
|
||||
|
||||

|
||||
|
||||
This card is fairly straight forward in that it'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're just
|
||||
quickly glancing at the dashboard, minutes ago is much faster brain processing than comparing the timestamp and the current
|
||||
time.
|
||||
|
||||
You've likely picked up by now that in the previous post, we never sent a payload to create the `sensor.bird_last_seen`
|
||||
entity. Here's how you can do it.
|
||||
|
||||
### Creating 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.
|
||||
|
||||
```jinja
|
||||
{{ now() - state_attr(sensor.bird_time_seen, 'last_triggered') > timedelta(hours=24) }}
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```jinja
|
||||
{% 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.
|
||||
|
||||
{{< box tip >}}
|
||||
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'll set parameters like not to notify you at night or during the winter months.
|
||||
{{< /box >}}
|
||||
|
||||
The 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 > Template to test relative
|
||||
time out on the `sensor.bird_time_seen` sensor, you'll get a result of 126 years... That's 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`.
|
||||
|
||||
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 `relative_time` function, you'll need to edit your `configuration.yaml`.
|
||||
|
||||
Once you're editing your config file, add the following:
|
||||
|
||||
```yaml
|
||||
template:
|
||||
# Bird Time Last Seen
|
||||
- sensor:
|
||||
- name: "Bird Last Seen"
|
||||
state: >
|
||||
{% 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 Assistant's templating functionality and creates a new sensor called "Bird Last Seen". The
|
||||
default `sensor.` name will be `sensor.bird_last_seen`.
|
||||
|
||||
To 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`. We're choosing this format because that
|
||||
is the format that `relative_time` returned before when we tried using it without a date.
|
||||
|
||||
As a quick experiment, take the templating code under the `state: >` parameter above and throw it into Developer Tools >
|
||||
Template. Do you get 126 years? Or something more realistic? If something more realistic, amazing!
|
||||
|
||||
We're almost there! Here's what you should see in HomeAssistant if the sensor was created correctly.
|
||||

|
||||
|
||||
{{< box info >}}
|
||||
If you'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.
|
||||
|
||||
* [HomeAssistant Templating Docs](https://www.home-assistant.io/docs/configuration/templating/)
|
||||
* [Jinja2 Templating Engine Docs](https://palletsprojects.com/p/jinja)
|
||||
|
||||
_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!_
|
||||
{{< /box >}}
|
||||
|
||||
{{< details "Data Card Yaml" >}}
|
||||
|
||||
```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 > 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 < 5) return '#ff6969';
|
||||
if (e < 10) return '#ffdf87';
|
||||
if (e < 15) return '#d9d76f';
|
||||
if (e < 20) return '#fcc2ea';
|
||||
else return '#ccccc8';
|
||||
]]]
|
||||
|
||||
```
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
## Weather Card
|
||||
|
||||

|
||||
|
||||
This doesn't need a lot of explaining or instructions. It is just the standard weather card! Here's the YAML, none of the
|
||||
less, so you know what I toggled on/off. I'm using [Pirate Weather Integration](https://pirateweather.net/en/latest/) as my
|
||||
data source.
|
||||
|
||||
{{< details "Weather Card" >}}
|
||||
|
||||
```yaml
|
||||
type: custom:weather-card
|
||||
entity: weather.pirateweather
|
||||
forecast: false
|
||||
hourly_forecast: false
|
||||
name: null
|
||||
details: true
|
||||
current: true
|
||||
number_of_forecasts: '5'
|
||||
```
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
## Description Card
|
||||
|
||||
Finally, we reach the bottom of the dashboard: the description card. This one is also really straightforward. We're just
|
||||
using a [standard markdown card](https://www.home-assistant.io/dashboards/markdown/) and taking the description sensor we
|
||||
created using Wikipedia's API and making that the main content of the card.
|
||||
|
||||

|
||||
|
||||
Other than setting the theme, the only other small changes are removing the border and increasing from the default font size.
|
||||
We'll use [Thomas Loven's](https://github.com/thomasloven) famous Card Mod for that.
|
||||
|
||||
{{< details "Description Card">}}
|
||||
|
||||
```yaml
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
## Conclusion
|
||||
|
||||
And that's all there is to it! I say that flippantly, but I know that it can seem like there's a lot of setup. Everything I
|
||||
did here evolved out of other people's projects and dashboards on [Reddit](www.reddit.com/r/homeassistant) or the invaluable
|
||||
[HomeAssistant Community](https://community.home-assistant.io/)
|
||||
|
||||
Please feel free to reach out to me on [Mastodon](www.fosstodon.org/@notnorm) if you have any questions or get stuck
|
||||
anywhere!
|
||||
|
||||
## Full Dashboard YAML
|
||||
|
||||
{{< details "Full Dashboard YAML" >}}
|
||||
|
||||
```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 > 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 < 5) return '#ff6969';
|
||||
if (e < 10) return '#ffdf87';
|
||||
if (e < 15) return '#d9d76f';
|
||||
if (e < 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;
|
||||
}
|
||||
```
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
<style>
|
||||
.box-shortcode {
|
||||
color: #e8e8e8;
|
||||
border: none;
|
||||
}
|
||||
.post-content img {
|
||||
margin: auto
|
||||
}
|
||||
</style>
|
||||
@ -20,11 +20,11 @@ ShowPostNavLinks: true
|
||||
ShowWordCount: true
|
||||
ShowRssButtonInSectionTermList: true
|
||||
UseHugoToc: true
|
||||
#cover:
|
||||
# image: "<image path/url>" # image path/url
|
||||
# alt: "<alt text>" # alt text
|
||||
# caption: "<text>" # display caption under cover
|
||||
# relative: false # when using page bundles set this to true
|
||||
cover:
|
||||
image: "hugo-nginx-trouble.png"
|
||||
alt: "Hugo Logo, Nginx Logo, Tired Face emoji"
|
||||
caption: "Hosting Hugo on a self-hosted nginx server brought some troubles!"
|
||||
relative: false # when using page bundles set this to true
|
||||
# hidden: true # only hide on current single page
|
||||
---
|
||||
|
||||
|
||||
BIN
content/posts/img/.DS_Store
vendored
Normal file
BIN
content/posts/img/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
content/posts/img/birdnet-homeassistant-birdseen-sensor.png
Normal file
BIN
content/posts/img/birdnet-homeassistant-birdseen-sensor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
content/posts/img/birdnet-homeassistant-dash-full.png
Normal file
BIN
content/posts/img/birdnet-homeassistant-dash-full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 250 KiB |
BIN
content/posts/img/birdnet-homeassistant-data-card.png
Normal file
BIN
content/posts/img/birdnet-homeassistant-data-card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
content/posts/img/birdnet-homeassistant-description-card.png
Normal file
BIN
content/posts/img/birdnet-homeassistant-description-card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
BIN
content/posts/img/birdnet-homeassistant-overview-card.png
Normal file
BIN
content/posts/img/birdnet-homeassistant-overview-card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
content/posts/img/birdnet-homeassistant-weather-card.png
Normal file
BIN
content/posts/img/birdnet-homeassistant-weather-card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
28
content/posts/zyxel_vlan_setup.md
Normal file
28
content/posts/zyxel_vlan_setup.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: 'Zyxel_vlan_setup'
|
||||
date: 2023-10-04T10:35:41-04:00
|
||||
tags: [""]
|
||||
author: "Me"
|
||||
showToc: true
|
||||
TocOpen: false
|
||||
draft: true
|
||||
hidemeta: false
|
||||
description: 'zyxel_vlan_setup'
|
||||
disableHLJS: true
|
||||
disableShare: false
|
||||
disableHLJS: false
|
||||
hideSummary: false
|
||||
searchHidden: true
|
||||
ShowReadingTime: true
|
||||
ShowBreadCrumbs: true
|
||||
ShowPostNavLinks: true
|
||||
ShowWordCount: true
|
||||
ShowRssButtonInSectionTermList: true
|
||||
UseHugoToc: true
|
||||
cover:
|
||||
image: ""
|
||||
alt: ""
|
||||
caption: ""
|
||||
relative: false
|
||||
hidden: true
|
||||
---
|
||||
Reference in New Issue
Block a user