Skip to content

Commit b3c8177

Browse files
committed
add devcontainer
1 parent 5941355 commit b3c8177

File tree

7 files changed

+140
-6
lines changed

7 files changed

+140
-6
lines changed

.devcontainer/devcontainer.json

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
1-
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2-
// README at: https://github.com/devcontainers/templates/tree/main/src/python
31
{
4-
"name": "Python 3",
5-
"image": "mcr.microsoft.com/devcontainers/python:1-3.13-bullseye",
6-
"postCreateCommand": "pip install -r requirements.txt"
2+
"name": "dkarv-devcontainer",
3+
"build": {
4+
"dockerfile": "../dev/Dockerfile"
5+
},
6+
"runArgs": [
7+
"--name",
8+
"dkarv-devcontainer"
9+
],
10+
"appPort": [
11+
8123
12+
],
13+
"postCreateCommand": "/workspaces/ha-lg-ess/dev/bootstrap.sh",
14+
"overrideCommand": false,
15+
"mounts": [
16+
"source=${localWorkspaceFolder}/dev/.config,target=/config,type=bind,consistency=cached",
17+
"source=${localWorkspaceFolder}/dev/configuration.yaml,target=/config/configuration.yaml,type=bind,consistency=cached",
18+
"source=${localWorkspaceFolder}/custom_components,target=/config/custom_components,type=bind,consistency=cached"
19+
],
20+
"features": {
21+
//"ghcr.io/devcontainers/features/python:1": "none"
22+
},
23+
"customizations": {
24+
"vscode": {
25+
"extensions": [
26+
"charliermarsh.ruff",
27+
"ms-python.pylint",
28+
"ms-python.vscode-pylance",
29+
"github.copilot-chat"
30+
]
31+
}
732
}
33+
}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
__pycache__/
1+
__pycache__/
2+
/dev/.config

.vscode/tasks.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "Follow devcontainer logs",
6+
"type": "shell",
7+
"command": "tail -n 1000 -f /var/log/ha.log",
8+
"presentation": {
9+
"echo": true,
10+
"reveal": "always",
11+
"panel": "dedicated",
12+
"showReuseMessage": false,
13+
"clear": false
14+
},
15+
"runOptions": {
16+
"runOn": "folderOpen"
17+
},
18+
"problemMatcher": []
19+
}
20+
]
21+
}

dev/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM homeassistant/home-assistant:2026.1
2+
3+
RUN apk add inotify-tools
4+
5+
COPY ./start.sh /start.sh
6+
7+
ENTRYPOINT ["/start.sh"]

dev/bootstrap.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
pip install -r requirements.txt
4+
# TODO find way to install dependencies from manifest.json directly

dev/configuration.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
# Loads default set of integrations. Do not remove.
3+
default_config:
4+
5+
# Load frontend themes from the themes folder
6+
frontend:
7+
themes: !include_dir_merge_named themes
8+
9+
automation: !include automations.yaml
10+
script: !include scripts.yaml
11+
scene: !include scenes.yaml
12+
13+
logger:
14+
default: info
15+
logs:
16+
custom_components: debug

dev/start.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Log everything to /var/log/ha.log while still printing to the console
5+
LOGFILE="/var/log/ha.log"
6+
touch "$LOGFILE" || true
7+
exec > >(tee -a "$LOGFILE") 2>&1
8+
9+
WATCH_DIR="/config/custom_components"
10+
DEBOUNCE=10
11+
12+
HA_CMD=(python -m homeassistant --config /config)
13+
HA_PID=0
14+
15+
start_ha() {
16+
echo "Starting Home Assistant..."
17+
"${HA_CMD[@]}" &
18+
HA_PID=$!
19+
echo "Home Assistant started with PID $HA_PID"
20+
}
21+
22+
stop_ha() {
23+
if [ "$HA_PID" -ne 0 ]; then
24+
echo "Stopping Home Assistant (PID $HA_PID)..."
25+
kill "$HA_PID" 2>/dev/null || true
26+
# wait up to 10s
27+
for i in {1..10}; do
28+
if kill -0 "$HA_PID" 2>/dev/null; then
29+
sleep 1
30+
else
31+
break
32+
fi
33+
done
34+
if kill -0 "$HA_PID" 2>/dev/null; then
35+
echo "Force killing Home Assistant (PID $HA_PID)"
36+
kill -9 "$HA_PID" 2>/dev/null || true
37+
fi
38+
wait "$HA_PID" 2>/dev/null || true
39+
HA_PID=0
40+
fi
41+
}
42+
43+
trap 'echo "Received termination signal, stopping..."; stop_ha; exit 0' INT TERM EXIT
44+
45+
start_ha
46+
47+
inotifywait -m -r -e close_write,modify,create,delete --format '%w%f' "$WATCH_DIR" | while read -r file; do
48+
# ignore changes in Python bytecode caches
49+
case "$file" in
50+
*/__pycache__/*)
51+
continue
52+
;;
53+
esac
54+
echo "Change detected: $file -- restarting Home Assistant"
55+
stop_ha
56+
start_ha
57+
sleep "$DEBOUNCE"
58+
done
59+

0 commit comments

Comments
 (0)