1
0
Fork 0

home-assistant: Manage YAML files with ConfigMap

Editing `configuration.yaml` et al. using `vi` via `kubectl exec` is
rather tedious, since the version of `vi` in the *home-assistant*
container image is very rudimentary.  Thus, I think it would be better
to use a ConfigMap to store the manually-edited YAML files, so I can
edit them with my regular editor on my desktop.  For this to work, the
ConfigMap has to be mounted as a directory rather than as individual
files (using `subPath`), as otherwise the pod would have to be restarted
every time one of the files is updated.
dch-webhooks-secrets
Dustin 2023-12-27 14:11:51 -06:00
parent 8d796a7c01
commit e56526600d
6 changed files with 368 additions and 0 deletions

View File

@ -50,6 +50,22 @@ exposed by a Service resource, which in turn is proxied by an Ingress resource.
[Home Assistant]: https://www.home-assistant.io/
#### ConfigMaps
Although most Home Assistant configuration is managed by its web UI, some
settings and integrations are read from manually-managed YAML files. Some
notable examples include the [Shell Command] and [Group] integrations. To make
it easier to edit these files, they are stored in a ConfigMap which is mounted
into the Home Assistant container. Since the Kublet will not automatically
update mounted ConfigMaps when files are mounted individually, the entire
ConfigMap has to be mounted as a directory. Files that must exist within the
configuration directory (i.e. `/config`) need symbolic links pointing to the
respective files in the ConfigMap mount point.
[Shell Command]: https://www.home-assistant.io/integrations/shell_command
[Group]: https://www.home-assistant.io/integrations/group
### PostgreSQL
Although Home Assistant stores all of its internal state in JSON files on the

View File

@ -0,0 +1,289 @@
assist_pipeline:
config:
counter:
energy:
frontend:
history:
image:
input_boolean:
input_button:
input_datetime:
input_number:
input_select:
input_text:
logbook:
map:
media_source:
mobile_app:
person:
schedule:
ssdp:
stream:
sun:
system_health:
tag:
timer:
webhook:
zeroconf:
zone:
http:
trusted_proxies:
- 172.30.0.160/28
use_x_forwarded_for: true
recorder:
db_url: !env_var RECORDER_DB_URL
db_max_retries: 100
purge_keep_days: 366
commit_interval: 0
homeassistant:
whitelist_external_dirs:
- /config
- /tmp
logger:
default: info
tts:
- platform: picotts
group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
shell_command: !include /run/config/shell-command.yaml
lovelace:
mode: storage
#dashboards: !include dashboards.yaml
#mqtt: !include mqtt.yaml
light:
- platform: group
name: Basement Lights
entities:
- light.desk_lamp_1
- light.desk_lamp_2
- light.desk_lamp_3
- light.light_2
- light.light_3
- light.light_4
- light.light_5
- light.light_6
- light.light_7
matrix:
homeserver: https://hatch.chat
username: '@homeassistant:hatch.chat'
password: !secret matrix_password
rooms:
- '!DdgnpVhlRqeTeNqSEM:hatch.chat'
- '!oyDXJxjUeJkEFshmAn:hatch.chat'
commands:
- word: snapshot
name: snapshot
- word: bunnies
name: bunnies
- expression: 'lights (?P<scene>.*)'
name: lights
notify:
- platform: matrix
name: matrix
default_room: '!DdgnpVhlRqeTeNqSEM:hatch.chat'
- platform: group
name: mobile_apps_group
services:
- service: mobile_app_pixel_5
- service: mobile_app_pixel_6a
- name: ntfy
platform: rest
method: POST_JSON
target_param_name: topic
title_param_name: title
message_param_name: message
resource: https://ntfy.pyrocufflink.net
- name: ntfy2
platform: ntfy
url: https://ntfy.pyrocufflink.net
default_topic: homeassistant
sensor:
- name: Rain last 24 hours
platform: statistics
entity_id: sensor.rain_gauge
unique_id: sensor.rain_last_24_hours
state_characteristic: change
max_age:
hours: 24
template:
- sensor:
- name: 'Thermostat Temperature'
device_class: temperature
unit_of_measurement: °C
state: >-
{% if is_state('sensor.season', 'winter') %}
{{ states('sensor.living_room_temperature') }}
{% else %}
{{ states('sensor.bedroom_temperature') }}
{% endif %}
- name: "Tonight's Forecast"
device_class: temperature
unit_of_measurement: °C
state: >-
{{ state_attr('weather.kojc_daynight', 'forecast')
| rejectattr('is_daytime')
| map(attribute='temperature')
| first }}
- name: Cost per Mow
device_class: monetary
unit_of_measurement: USD
state: >-
{{ 3072.21 / states('counter.mow_count')|int }}
- name: Apc1500 Load
device_class: power
unit_of_measurement: W
state: >-
{{ "%.1f" | format(
states('sensor.apc1500_load') | float / 100
* states('sensor.apc1500_nominal_real_power') | float
)
}}
- name: Apc1300 Load
device_class: power
unit_of_measurement: W
state: >-
{{ "%.1f" | format(
states('sensor.apc1300_load') | float / 100
* states('sensor.apc1300_nominal_real_power') | float
)
}}
cover:
- platform: template
covers:
garage_door_1:
device_class: garage
friendly_name: "Garage Door 1"
value_template: >-
{% if is_state('binary_sensor.garage_door_1_window_door_is_open', 'on') %}
open
{% else %}
closed
{% endif %}
open_cover:
service: switch.turn_on
target:
entity_id: switch.garage_door_relay_3
close_cover:
service: switch.turn_on
target:
entity_id: switch.garage_door_relay_3
icon_template: >-
{% if is_state('binary_sensor.garage_door_1_window_door_is_open', 'on') %}
mdi:garage-open
{% else %}
mdi:garage
{% endif %}
- platform: template
covers:
garage_door_2:
device_class: garage
friendly_name: "Garage Door 2"
value_template: >-
{% if is_state('binary_sensor.garage_door_2_window_door_is_open', 'on') %}
open
{% else %}
closed
{% endif %}
open_cover:
service: switch.turn_on
target:
entity_id: switch.garage_door_relay_2_2
close_cover:
service: switch.turn_on
target:
entity_id: switch.garage_door_relay_2_2
icon_template: >-
{% if is_state('binary_sensor.garage_door_2_window_door_is_open', 'on') %}
mdi:garage-open
{% else %}
mdi:garage
{% endif %}
- platform: template
covers:
garage_door_3:
device_class: garage
friendly_name: "Garage Door 3"
value_template: >-
{% if is_state('binary_sensor.garage_door_3_window_door_is_open', 'on') %}
open
{% else %}
closed
{% endif %}
open_cover:
service: switch.turn_on
target:
entity_id: switch.garage_door_relay_2
close_cover:
service: switch.turn_on
target:
entity_id: switch.garage_door_relay_2
icon_template: >-
{% if is_state('binary_sensor.garage_door_3_window_door_is_open', 'on') %}
mdi:garage-open
{% else %}
mdi:garage
{% endif %}
switch:
- platform: wake_on_lan
name: Rosalina
host: rosalina.pyrocufflink.blue
mac: 0c:9d:92:0e:3a:41
- platform: wake_on_lan
name: vmhost0
host: vmhost0.pyrocufflink.blue
mac: e0:d5:5e:a2:2e:1a
- platform: wake_on_lan
name: vmhost1
host: vmhost1.pyrocufflink.blue
mac: 18:c0:4d:90:4d:00
- platform: wake_on_lan
name: Toad
host: toad.pyrocufflink.blue
mac: 1c:1b:0d:0f:ad:df
- platform: wake_on_lan
name: Sonic
host: sonic.pyrocufflink.blue
mac: e0:d5:5e:6e:ad:ac
broadcast_address: 172.30.0.63
binary_sensor:
- platform: template
sensors:
roomba_is_downstairs:
friendly_name: Roomba is Downstairs
value_template: >-
{% if is_state('binary_sensor.roomba_ibeacon_ble_presence', 'on') and
states('sensor.roomba_ibeacon_ble_rssi') | float > -70 %}
on
{% else %}
off
{% endif %}
prometheus:
filter:
exclude_entity_globs:
- binary_sensor.node_14*
- binary_sensor.node_15*

View File

@ -0,0 +1,15 @@
family:
entities:
- person.dustin
- person.tabitha
name: Family
watch_view:
entities:
- cover.garage_door_3
- cover.garage_door_2
- cover.garage_door_1
- light.front_porch_light
- light.back_porch_light
- light.back_porch_flood_light
- light.garage_lights
name: Watch View

View File

@ -20,6 +20,18 @@ resources:
- ingress.yaml
configMapGenerator:
- name: home-assistant
files:
- configuration.yaml
- groups.yaml
- shell-command.yaml
options:
disableNameSuffixHash: true
labels:
app.kubernetes.io/name: home-assistant
app.kubernetes.io/component: home-assistant
app.kubernetes.io/part-of: home-assistant
- name: mosquitto
files:
- mosquitto.conf
@ -48,3 +60,19 @@ patches:
key: username
- name: RECORDER_DB_URL
value: postgresql://$(RECORDER_DB_USERNAME):$(RECORDER_DB_PASSWORD)@default.postgresql/homeassistant
volumeMounts:
- mountPath: /run/config
name: home-assistant-config
readOnly: true
- mountPath: /run/secrets/home-assistant
name: home-assistant-secrets
readOnly: true
volumes:
- name: home-assistant-config
configMap:
name: home-assistant
defaultMode: 0600
- name: home-assistant-secrets
secret:
secretName: home-assistant
defaultMode: 0640

View File

@ -13,3 +13,21 @@ spec:
creationTimestamp: null
name: mosquitto
namespace: home-assistant
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: home-assistant
namespace: home-assistant
labels:
app.kubernetes.io/name: home-assistant
app.kubernetes.io/component: home-assistant
app.kubernetes.io/part-of: home-assistant
spec:
encryptedData:
secrets.yaml: AgAcQGBxXTW6s/4lcGoyKYn9NL7h4L8rbFeC87GbXQunVD4h37kiET55c5AgSj95X0Y8Vn9EYgd85xY5vDjxkAQ8qmcBL0SlrHuAxlRONoVDIgUmGIk91p4boVXp4Db+DzvtezjCruraIh4MgVQS9nS30MG3PWb/IfsHeaGNAyIL6OCdJYWTIUD9ceCdCNrTCeK45qow+ZHYhwpw6puXLQEq45j1UX1fgCsnNfYxDXRoW/vOwFLnOfN6JTjSyu28Qo4jIqu0iF26hMViU+ok/eYzC9J0fpfwGHhDdGMI29cWYyTS+L0BBbV37mMPx7UKYShweL6kK6Ar2ewB6tFQzr4eHcX6Qb8EuNYKBHz9kLrgZp54diUuiX1thjwbSLkv+HJa4voKyvsab3Nug4FJPlvg6R6J852dpmFK1ElK5ejkGaqfvT0iqGA1AvQe51FOSOARjC9/g29i6T5S5+5Cc3igJdfiadd3vTWTKpR0kf7mvoL4MT4OGPvir2O1bjXB5Mv9zDt2Cm+ZD5ve3n4Dq5WqOvkJN9FJMRe04rM1a1yP8lSzuil20OVDc1N4wrCtPJ71bqsNpLAbsYy2E/t2gU1UVM+HkkA9FucAQs5fs8Fe5fYsYLg6zUtM6i9fB+Y1JbAY9GWYMAA+enkrkAHLqxxFF1g5Dc9cpmyP+1fu5jy2BF0GfmIPuyuUTch/20pngnoFLM9JdkRP0SkgJ4/wtAnWKY1twbUPjb/L53rEpZWICPbJjR19Y1FycDwAauZmTmg8ZQ0ro1uh77rbTsCmViUKwXsrSUTY7mGmD5q4LCtRZqWRBDt3Hl5jHvhzvUSGeso+YnnaLr6GXYdRkibxWA5X6SG1iBHoQzKqUPO28Ybsnv6Au4RloDU2TAAUNnl32L0Kq4yjIwlAq9r2ASWwgUJUqU12i3wnC4iHrE6jeLQSQ6yrkJOrUyizaPJWfr/4JFeLVOcBM1SjR0y/dtuWnPvgItsTHwDJyw==
template:
metadata:
name: home-assistant
namespace: home-assistant

View File

@ -0,0 +1,2 @@
restart_diddy_mopidy: >-
ssh -i /config/homeassistant-ssh.pem -oUserKnownHostsFile=/config/ssh_known_hosts -oBatchMode=yes pi@diddy.pyrocufflink.red restart-mopidy