Compare commits
8 Commits
9e061b7078
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f8dacd3122 | |||
| 6e1b7eab74 | |||
| f0af1eacfa | |||
| 1ee7f0c739 | |||
| 8f7bae56db | |||
| 962628912d | |||
| 0bff60aa45 | |||
| 1d6dce7b42 |
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
## What this repo is
|
## What this repo is
|
||||||
|
|
||||||
The Home Assistant configuration directory (`/config` on the live HAOS host, mirrored to this git repo). It is **configuration, not application code** — there is no build or test suite. "Running" a change means HA loads it; validation is by config-check and reload, not unit tests. The repo is also mirrored to a self-hosted Gitea at `code.cubecraftcreations.com`.
|
The Home Assistant configuration directory (`/config` on the live HAOS host, mirrored to this git repo). It is **configuration, not application code** — there is no build or test suite. "Running" a change means HA loads it; validation is by config-check and reload, not unit tests. The repo is also mirrored to a self-hosted Gitea at `code.cubecraftlabs.com` (`origin` is `https://code.cubecraftlabs.com/overseer/Home-Assistant.git`).
|
||||||
|
|
||||||
Edits here only take effect after they reach the live host and HA reloads the affected domain. There is no compile step; a malformed YAML file breaks the domain it belongs to (or all of HA if it's `configuration.yaml`).
|
Edits here only take effect after they reach the live host and HA reloads the affected domain. There is no compile step; a malformed YAML file breaks the domain it belongs to (or all of HA if it's `configuration.yaml`).
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
homeassistant:
|
homeassistant:
|
||||||
packages: !include_dir_named packages/
|
packages: !include_dir_named packages/
|
||||||
|
auth_providers:
|
||||||
|
- type: trusted_networks
|
||||||
|
trusted_networks:
|
||||||
|
- 192.168.69.0/24
|
||||||
|
- 10.60.1.0/24
|
||||||
|
trusted_users:
|
||||||
|
192.168.69.0/24: 66e8deaeb6944b65a6ed652d671599e2
|
||||||
|
10.60.1.0/24: 66e8deaeb6944b65a6ed652d671599e2
|
||||||
|
allow_bypass_login: true
|
||||||
|
- type: homeassistant
|
||||||
|
|
||||||
# Loads default set of integrations. Do not remove.
|
# Loads default set of integrations. Do not remove.
|
||||||
default_config:
|
default_config:
|
||||||
@@ -34,6 +44,8 @@ http:
|
|||||||
use_x_forwarded_for: true
|
use_x_forwarded_for: true
|
||||||
trusted_proxies:
|
trusted_proxies:
|
||||||
- 10.60.1.1
|
- 10.60.1.1
|
||||||
|
cors_allowed_origins:
|
||||||
|
- https://dakboard.com
|
||||||
|
|
||||||
### notify_events ###
|
### notify_events ###
|
||||||
notify_events:
|
notify_events:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
voice-alarms: !include voice-alarms.yaml
|
voice-alarms: !include voice-alarms.yaml
|
||||||
family-hub: !include family-hub.yaml
|
family-hub: !include family-hub.yaml
|
||||||
at-a-glance: !include at-a-glance.yaml
|
at-a-glance: !include at-a-glance.yaml
|
||||||
|
lunch-menus: !include lunch-menus.yaml
|
||||||
# Each key is the dashboard's url_path, and HA requires it to contain a hyphen
|
# Each key is the dashboard's url_path, and HA requires it to contain a hyphen
|
||||||
# (see homeassistant/components/lovelace: url_path validation). A hyphen-less
|
# (see homeassistant/components/lovelace: url_path validation). A hyphen-less
|
||||||
# key fails validation for the whole `lovelace:` block, not just its own entry,
|
# key fails validation for the whole `lovelace:` block, not just its own entry,
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
mode: yaml
|
||||||
|
title: Lunch Menus
|
||||||
|
icon: mdi:food-apple
|
||||||
|
show_in_sidebar: true
|
||||||
|
filename: dashboards/views/lunch-menus-dashboard.yaml
|
||||||
@@ -80,23 +80,18 @@ views:
|
|||||||
round_temperature: false
|
round_temperature: false
|
||||||
|
|
||||||
# ── Family Calendar ──
|
# ── Family Calendar ──
|
||||||
- type: calendar
|
# Daylight Calendar Card (HACS: daylight-calendar-card). Agenda mirrors
|
||||||
|
# the old stock listWeek “upcoming” feel on a wall panel.
|
||||||
|
- type: custom:daylight-calendar-card
|
||||||
title: Upcoming Events
|
title: Upcoming Events
|
||||||
initial_view: listWeek
|
default_view: agenda
|
||||||
|
color_scheme: auto
|
||||||
|
preference_storage_key: family_hub_calendar
|
||||||
entities:
|
entities:
|
||||||
- calendar.family_events
|
- calendar.family_events
|
||||||
- calendar.birthdays
|
- calendar.birthdays
|
||||||
- calendar.holidays_in_united_states
|
- calendar.holidays_in_united_states
|
||||||
- calendar.gmail_calendar
|
- calendar.gmail_calendar
|
||||||
card_mod:
|
|
||||||
style: |
|
|
||||||
ha-card {
|
|
||||||
--calendar-day-color: var(--cc-text, var(--primary-text-color));
|
|
||||||
--calendar-day-weekday-color: var(--cc-text-muted, var(--secondary-text-color));
|
|
||||||
--fc-today-bg-color: var(--cc-accent-soft);
|
|
||||||
--fc-event-bg-color: var(--cc-accent);
|
|
||||||
--fc-event-border-color: var(--cc-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Quick Glance ──
|
# ── Quick Glance ──
|
||||||
- type: heading
|
- type: heading
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
# Lunch Menus — school cafeteria calendars (Mon–Fri each)
|
||||||
|
#
|
||||||
|
# Panel layout so the title spans the full width and the three school cards
|
||||||
|
# sit in one row. Menus come from packages/lunch_menus.yaml (stock calendar
|
||||||
|
# cards cannot limit to a school-week window).
|
||||||
|
title: Lunch Menus
|
||||||
|
theme: cubecraft
|
||||||
|
views:
|
||||||
|
- title: Lunch Menus
|
||||||
|
path: lunch-menus
|
||||||
|
icon: mdi:food-apple
|
||||||
|
theme: cubecraft
|
||||||
|
type: panel
|
||||||
|
cards:
|
||||||
|
- type: vertical-stack
|
||||||
|
cards:
|
||||||
|
- type: markdown
|
||||||
|
content: |
|
||||||
|
{% set wd = now().weekday() %}
|
||||||
|
{% if wd >= 5 %}
|
||||||
|
{% set monday = today_at() + timedelta(days=(7 - wd)) %}
|
||||||
|
{% else %}
|
||||||
|
{% set monday = today_at() - timedelta(days=wd) %}
|
||||||
|
{% endif %}
|
||||||
|
{% set friday = monday + timedelta(days=4) %}
|
||||||
|
# School Lunch Menus
|
||||||
|
## {{ monday.strftime("%b %-d") }} – {{ friday.strftime("%b %-d, %Y") }}
|
||||||
|
card_mod:
|
||||||
|
style: |
|
||||||
|
ha-card {
|
||||||
|
background: var(--cc-gradient);
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--cc-radius-brand);
|
||||||
|
box-shadow: var(--cc-shadow-brand);
|
||||||
|
padding: 6px 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
ha-card h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
opacity: 0.85;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
ha-card h2 {
|
||||||
|
margin: 2px 0 0 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
- type: grid
|
||||||
|
columns: 3
|
||||||
|
square: false
|
||||||
|
cards:
|
||||||
|
- type: markdown
|
||||||
|
title: BHS Lunch Menu
|
||||||
|
entity_id: sensor.bhs_lunch_menu_week
|
||||||
|
content: |
|
||||||
|
{% set events = state_attr('sensor.bhs_lunch_menu_week', 'events') or [] %}
|
||||||
|
{% if events is string %}{% set events = [] %}{% endif %}
|
||||||
|
{% set wd = now().weekday() %}
|
||||||
|
{% if wd >= 5 %}
|
||||||
|
{% set monday = today_at() + timedelta(days=(7 - wd)) %}
|
||||||
|
{% else %}
|
||||||
|
{% set monday = today_at() - timedelta(days=wd) %}
|
||||||
|
{% endif %}
|
||||||
|
{% for offset in range(5) %}
|
||||||
|
{% set d = (monday + timedelta(days=offset)).date() %}
|
||||||
|
{% set d_str = d.isoformat() %}
|
||||||
|
{% set ns = namespace(found=false) %}
|
||||||
|
### {{ d.strftime("%A") }}
|
||||||
|
{{ d.strftime("%b %-d") }}
|
||||||
|
{% for e in events if e.start is defined and e.start[:10] == d_str %}
|
||||||
|
{% set ns.found = true %}
|
||||||
|
- {{ e.summary }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if not ns.found %}
|
||||||
|
_No menu listed_
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
card_mod: &cc_menu
|
||||||
|
style: |
|
||||||
|
ha-card .card-header {
|
||||||
|
color: var(--cc-text, var(--primary-text-color));
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
ha-markdown {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
ha-markdown h3 {
|
||||||
|
margin: 0.85rem 0 0.15rem 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--cc-accent, var(--primary-color));
|
||||||
|
}
|
||||||
|
ha-markdown h3:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
ha-markdown p {
|
||||||
|
margin: 0 0 0.35rem 0;
|
||||||
|
color: var(--cc-text-muted, var(--secondary-text-color));
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
ha-markdown ul {
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
padding-left: 1.1rem;
|
||||||
|
}
|
||||||
|
ha-markdown li {
|
||||||
|
margin: 0.15rem 0;
|
||||||
|
color: var(--cc-text, var(--primary-text-color));
|
||||||
|
}
|
||||||
|
ha-markdown em {
|
||||||
|
color: var(--cc-text-muted, var(--secondary-text-color));
|
||||||
|
}
|
||||||
|
|
||||||
|
- type: markdown
|
||||||
|
title: BIS School Lunches
|
||||||
|
entity_id: sensor.bis_lunch_menu_week
|
||||||
|
content: |
|
||||||
|
{% set events = state_attr('sensor.bis_lunch_menu_week', 'events') or [] %}
|
||||||
|
{% if events is string %}{% set events = [] %}{% endif %}
|
||||||
|
{% set wd = now().weekday() %}
|
||||||
|
{% if wd >= 5 %}
|
||||||
|
{% set monday = today_at() + timedelta(days=(7 - wd)) %}
|
||||||
|
{% else %}
|
||||||
|
{% set monday = today_at() - timedelta(days=wd) %}
|
||||||
|
{% endif %}
|
||||||
|
{% for offset in range(5) %}
|
||||||
|
{% set d = (monday + timedelta(days=offset)).date() %}
|
||||||
|
{% set d_str = d.isoformat() %}
|
||||||
|
{% set ns = namespace(found=false) %}
|
||||||
|
### {{ d.strftime("%A") }}
|
||||||
|
{{ d.strftime("%b %-d") }}
|
||||||
|
{% for e in events if e.start is defined and e.start[:10] == d_str %}
|
||||||
|
{% set ns.found = true %}
|
||||||
|
- {{ e.summary }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if not ns.found %}
|
||||||
|
_No menu listed_
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
card_mod: *cc_menu
|
||||||
|
|
||||||
|
- type: markdown
|
||||||
|
title: HMS Lunch Menu
|
||||||
|
entity_id: sensor.hms_lunch_menu_week
|
||||||
|
content: |
|
||||||
|
{% set events = state_attr('sensor.hms_lunch_menu_week', 'events') or [] %}
|
||||||
|
{% if events is string %}{% set events = [] %}{% endif %}
|
||||||
|
{% set wd = now().weekday() %}
|
||||||
|
{% if wd >= 5 %}
|
||||||
|
{% set monday = today_at() + timedelta(days=(7 - wd)) %}
|
||||||
|
{% else %}
|
||||||
|
{% set monday = today_at() - timedelta(days=wd) %}
|
||||||
|
{% endif %}
|
||||||
|
{% for offset in range(5) %}
|
||||||
|
{% set d = (monday + timedelta(days=offset)).date() %}
|
||||||
|
{% set d_str = d.isoformat() %}
|
||||||
|
{% set ns = namespace(found=false) %}
|
||||||
|
### {{ d.strftime("%A") }}
|
||||||
|
{{ d.strftime("%b %-d") }}
|
||||||
|
{% for e in events if e.start is defined and e.start[:10] == d_str %}
|
||||||
|
{% set ns.found = true %}
|
||||||
|
- {{ e.summary }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if not ns.found %}
|
||||||
|
_No menu listed_
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
card_mod: *cc_menu
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
################################################################################
|
||||||
|
# lunch_menus.yaml
|
||||||
|
#
|
||||||
|
# Pulls Mon–Fri of the current school week from each lunch Google Calendar into
|
||||||
|
# template sensors. On Sat/Sun, advances to next week's Monday. The Lunch Menus
|
||||||
|
# dashboard renders those attributes — the stock calendar card has no school-
|
||||||
|
# week view.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
template:
|
||||||
|
- trigger:
|
||||||
|
- platform: time_pattern
|
||||||
|
minutes: "/15"
|
||||||
|
- platform: homeassistant
|
||||||
|
event: start
|
||||||
|
- platform: event
|
||||||
|
event_type: event_template_reloaded
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
# weekday(): Mon=0 … Sun=6. Weekend → next Monday.
|
||||||
|
school_monday: >-
|
||||||
|
{% set wd = now().weekday() %}
|
||||||
|
{% if wd >= 5 %}
|
||||||
|
{{ (today_at() + timedelta(days=(7 - wd))).isoformat() }}
|
||||||
|
{% else %}
|
||||||
|
{{ (today_at() - timedelta(days=wd)).isoformat() }}
|
||||||
|
{% endif %}
|
||||||
|
- action: calendar.get_events
|
||||||
|
target:
|
||||||
|
entity_id:
|
||||||
|
- calendar.bhs_lunch_menu
|
||||||
|
- calendar.bis_school_lunches
|
||||||
|
- calendar.hms_lunch_menu
|
||||||
|
data:
|
||||||
|
start_date_time: "{{ school_monday }}"
|
||||||
|
duration:
|
||||||
|
days: 5
|
||||||
|
response_variable: agenda
|
||||||
|
sensor:
|
||||||
|
- name: "BHS Lunch Menu Week"
|
||||||
|
unique_id: bhs_lunch_menu_week
|
||||||
|
icon: mdi:food-apple
|
||||||
|
state: "{{ agenda['calendar.bhs_lunch_menu'].events | count }}"
|
||||||
|
attributes:
|
||||||
|
events: "{{ agenda['calendar.bhs_lunch_menu'].events }}"
|
||||||
|
week_start: "{{ school_monday }}"
|
||||||
|
|
||||||
|
- name: "BIS Lunch Menu Week"
|
||||||
|
unique_id: bis_lunch_menu_week
|
||||||
|
icon: mdi:food-apple
|
||||||
|
state: "{{ agenda['calendar.bis_school_lunches'].events | count }}"
|
||||||
|
attributes:
|
||||||
|
events: "{{ agenda['calendar.bis_school_lunches'].events }}"
|
||||||
|
week_start: "{{ school_monday }}"
|
||||||
|
|
||||||
|
- name: "HMS Lunch Menu Week"
|
||||||
|
unique_id: hms_lunch_menu_week
|
||||||
|
icon: mdi:food-apple
|
||||||
|
state: "{{ agenda['calendar.hms_lunch_menu'].events | count }}"
|
||||||
|
attributes:
|
||||||
|
events: "{{ agenda['calendar.hms_lunch_menu'].events }}"
|
||||||
|
week_start: "{{ school_monday }}"
|
||||||
@@ -55,6 +55,6 @@ The finish automation condition checks `| length == 36` on the stored ID.
|
|||||||
## HA Setup
|
## HA Setup
|
||||||
|
|
||||||
- HAOS on x86 server
|
- HAOS on x86 server
|
||||||
- Gitea repo at code.cubecraftcreations.com (username: overseer)
|
- Gitea repo at code.cubecraftlabs.com (username: overseer)
|
||||||
- IoT VLAN: 192.168.69.x, Main: 192.168.1.x
|
- IoT VLAN: 192.168.69.x, Main: 192.168.1.x
|
||||||
- ~150 devices, UniFi networking
|
- ~150 devices, UniFi networking
|
||||||
|
|||||||
Reference in New Issue
Block a user