-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathampctl
More file actions
executable file
·152 lines (143 loc) · 3.47 KB
/
Copy pathampctl
File metadata and controls
executable file
·152 lines (143 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env bash
# ampctl - control amplifier power via GPIO SHDN pins
#
# GPIO mapping is read from speaker_config.json's `amplifiers.<id>.gpio`
# field per amp. Amps without a `gpio` field are treated as ALWAYS ON:
# status reports "on" and on/off are no-ops (so powermanager/webui keep
# working when an amp is wired straight to power and has no SHDN line).
#
# Usage:
# ampctl status Show status of all amps (JSON)
# ampctl status amp1 Show status of one amp ("amp on" / "amp off")
# ampctl on [amp] Power on (one amp, or all)
# ampctl off [amp] Power off (one amp, or all)
SPEAKER_CONFIG="${SPEAKER_CONFIG:-/home/tobias/multiroom-tooling/speaker_config.json}"
_amp_gpio() {
python3 - "$SPEAKER_CONFIG" "$1" <<'PY' 2>/dev/null
import json, sys
try:
c = json.load(open(sys.argv[1]))
except Exception:
sys.exit(0)
amp = (c.get('amplifiers') or {}).get(sys.argv[2]) or {}
g = amp.get('gpio')
if isinstance(g, int):
print(g)
PY
}
_all_amps() {
python3 - "$SPEAKER_CONFIG" <<'PY' 2>/dev/null
import json, sys
try:
c = json.load(open(sys.argv[1]))
except Exception:
sys.exit(0)
for k in sorted((c.get('amplifiers') or {}).keys()):
print(k)
PY
}
_amp_known() {
_all_amps | grep -qx "$1"
}
get_state() {
local amp=$1
local gpio
gpio=$(_amp_gpio "$amp")
if [[ -z "$gpio" ]]; then
# No GPIO configured → amp is hard-wired on (or has no SHDN line);
# we have no way to read or change its state, so report "on".
echo "on"
return
fi
local output
output=$(pinctrl get "$gpio" 2>/dev/null)
if [[ "$output" == *"| hi"* ]]; then
echo "on"
elif [[ "$output" == *"| lo"* ]]; then
echo "off"
else
echo "unknown"
fi
}
amp_on() {
local amp=$1
local gpio
gpio=$(_amp_gpio "$amp")
[[ -n "$gpio" ]] && pinctrl set "$gpio" op dh 2>/dev/null
# else: no GPIO → always on, nothing to toggle
}
amp_off() {
local amp=$1
local gpio
gpio=$(_amp_gpio "$amp")
[[ -n "$gpio" ]] && pinctrl set "$gpio" op dl 2>/dev/null
# else: no GPIO → always on, nothing to toggle (off is a no-op)
}
case "${1:-}" in
status)
if [[ -n "${2:-}" ]]; then
amp="$2"
if ! _amp_known "$amp"; then
echo "Unknown amp: $amp" >&2
exit 1
fi
state=$(get_state "$amp")
echo "$amp $state"
else
echo "{"
first=true
mapfile -t _amps < <(_all_amps)
for amp in "${_amps[@]}"; do
state=$(get_state "$amp")
$first || echo ","
printf ' "%s": "%s"' "$amp" "$state"
first=false
done
echo ""
echo "}"
fi
;;
on)
if [[ -n "${2:-}" ]]; then
amp="$2"
if ! _amp_known "$amp"; then
echo "Unknown amp: $amp" >&2
exit 1
fi
amp_on "$amp"
echo "$amp on"
else
mapfile -t _amps < <(_all_amps)
for amp in "${_amps[@]}"; do
amp_on "$amp"
echo "$amp on"
done
fi
;;
off)
if [[ -n "${2:-}" ]]; then
amp="$2"
if ! _amp_known "$amp"; then
echo "Unknown amp: $amp" >&2
exit 1
fi
amp_off "$amp"
echo "$amp off"
else
mapfile -t _amps < <(_all_amps)
for amp in "${_amps[@]}"; do
amp_off "$amp"
echo "$amp off"
done
fi
;;
*)
cat <<USAGE >&2
Usage: ampctl {status|on|off} [amp_id]
GPIO mapping is read from $SPEAKER_CONFIG
(amplifiers.<id>.gpio). Amps without a gpio field are treated as
always-on (status: on; on/off are no-ops).
USAGE
exit 1
;;
esac