Add remote volume control for the living room media center (boxy) that controls the Denon AVR through Home Assistant instead of local audio. - Create plasma-manager-kodi role with custom KDE hotkeys for volume up/down/mute that execute shell scripts - Scripts retrieve HA token from KDE Wallet and send API requests to control media_player.denon_avr_s970h_2 - Add retry logic (3 attempts) and error notifications - Enable KDE Wallet PAM integration for automatic wallet unlock - Configure KDE settings: Breeze Dark theme, disable screen locking, empty session restore - Add kconfig package for debugging tools
200 lines
6.0 KiB
Nix
200 lines
6.0 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.home.roles.plasma-manager-kodi;
|
|
|
|
# Define the volume control scripts as derivations
|
|
volumeUpScript = pkgs.writeShellScript "avr-volume-up" ''
|
|
#!/usr/bin/env bash
|
|
|
|
# Configuration
|
|
HA_URL="https://home-assistant.johnogle.info"
|
|
ENTITY_ID="media_player.denon_avr_s970h_2"
|
|
MAX_RETRIES=3
|
|
|
|
# Read token from KDE Wallet and strip whitespace
|
|
TOKEN=$(${pkgs.kdePackages.kwallet}/bin/kwallet-query -r ha_avr_token kdewallet -f Passwords 2>/dev/null | tr -d '[:space:]')
|
|
|
|
if [ -z "$TOKEN" ]; then
|
|
${pkgs.libnotify}/bin/notify-send -u critical "Volume Control Error" "Failed to retrieve Home Assistant token from KDE Wallet"
|
|
exit 1
|
|
fi
|
|
|
|
# Send volume up command with retry logic
|
|
for i in $(seq 1 $MAX_RETRIES); do
|
|
RESPONSE=$(${pkgs.curl}/bin/curl -s -w "\n%{http_code}" -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"entity_id\": \"$ENTITY_ID\"}" \
|
|
"$HA_URL/api/services/media_player/volume_up" 2>&1)
|
|
|
|
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Wait before retry (except on last attempt)
|
|
if [ $i -lt $MAX_RETRIES ]; then
|
|
sleep 0.5
|
|
fi
|
|
done
|
|
|
|
# All retries failed
|
|
${pkgs.libnotify}/bin/notify-send -u critical "Volume Control Error" "Failed to increase volume after $MAX_RETRIES attempts"
|
|
exit 1
|
|
'';
|
|
|
|
volumeDownScript = pkgs.writeShellScript "avr-volume-down" ''
|
|
#!/usr/bin/env bash
|
|
|
|
# Configuration
|
|
HA_URL="https://home-assistant.johnogle.info"
|
|
ENTITY_ID="media_player.denon_avr_s970h_2"
|
|
MAX_RETRIES=3
|
|
|
|
# Read token from KDE Wallet and strip whitespace
|
|
TOKEN=$(${pkgs.kdePackages.kwallet}/bin/kwallet-query -r ha_avr_token kdewallet -f Passwords 2>/dev/null | tr -d '[:space:]')
|
|
|
|
if [ -z "$TOKEN" ]; then
|
|
${pkgs.libnotify}/bin/notify-send -u critical "Volume Control Error" "Failed to retrieve Home Assistant token from KDE Wallet"
|
|
exit 1
|
|
fi
|
|
|
|
# Send volume down command with retry logic
|
|
for i in $(seq 1 $MAX_RETRIES); do
|
|
RESPONSE=$(${pkgs.curl}/bin/curl -s -w "\n%{http_code}" -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"entity_id\": \"$ENTITY_ID\"}" \
|
|
"$HA_URL/api/services/media_player/volume_down" 2>&1)
|
|
|
|
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Wait before retry (except on last attempt)
|
|
if [ $i -lt $MAX_RETRIES ]; then
|
|
sleep 0.5
|
|
fi
|
|
done
|
|
|
|
# All retries failed
|
|
${pkgs.libnotify}/bin/notify-send -u critical "Volume Control Error" "Failed to decrease volume after $MAX_RETRIES attempts"
|
|
exit 1
|
|
'';
|
|
|
|
volumeMuteScript = pkgs.writeShellScript "avr-volume-mute" ''
|
|
#!/usr/bin/env bash
|
|
|
|
# Configuration
|
|
HA_URL="https://home-assistant.johnogle.info"
|
|
ENTITY_ID="media_player.denon_avr_s970h_2"
|
|
MAX_RETRIES=3
|
|
|
|
# Read token from KDE Wallet and strip whitespace
|
|
TOKEN=$(${pkgs.kdePackages.kwallet}/bin/kwallet-query -r ha_avr_token kdewallet -f Passwords 2>/dev/null | tr -d '[:space:]')
|
|
|
|
if [ -z "$TOKEN" ]; then
|
|
${pkgs.libnotify}/bin/notify-send -u critical "Volume Control Error" "Failed to retrieve Home Assistant token from KDE Wallet"
|
|
exit 1
|
|
fi
|
|
|
|
# Get current mute state
|
|
STATE_RESPONSE=$(${pkgs.curl}/bin/curl -s -H "Authorization: Bearer $TOKEN" \
|
|
"$HA_URL/api/states/$ENTITY_ID")
|
|
|
|
CURRENT_MUTE=$(echo "$STATE_RESPONSE" | ${pkgs.jq}/bin/jq -r '.attributes.is_volume_muted // false')
|
|
|
|
# Toggle: if currently muted (true), unmute (false), and vice versa
|
|
if [ "$CURRENT_MUTE" = "true" ]; then
|
|
NEW_MUTE="false"
|
|
NOTIFY_MSG="Unmuted"
|
|
else
|
|
NEW_MUTE="true"
|
|
NOTIFY_MSG="Muted"
|
|
fi
|
|
|
|
# Send mute toggle command with retry logic
|
|
for i in $(seq 1 $MAX_RETRIES); do
|
|
RESPONSE=$(${pkgs.curl}/bin/curl -s -w "\n%{http_code}" -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"entity_id\": \"$ENTITY_ID\", \"is_volume_muted\": $NEW_MUTE}" \
|
|
"$HA_URL/api/services/media_player/volume_mute" 2>&1)
|
|
|
|
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Wait before retry (except on last attempt)
|
|
if [ $i -lt $MAX_RETRIES ]; then
|
|
sleep 0.5
|
|
fi
|
|
done
|
|
|
|
# All retries failed
|
|
${pkgs.libnotify}/bin/notify-send -u critical "Volume Control Error" "Failed to toggle mute after $MAX_RETRIES attempts"
|
|
exit 1
|
|
'';
|
|
in
|
|
{
|
|
options.home.roles.plasma-manager-kodi = {
|
|
enable = mkEnableOption "KDE Plasma volume control for kodi user via Home Assistant";
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
programs.plasma = {
|
|
enable = true;
|
|
overrideConfig = true;
|
|
|
|
# Disable default kmix volume shortcuts to prevent conflicts
|
|
shortcuts.kmix = {
|
|
"increase_volume" = "none";
|
|
"decrease_volume" = "none";
|
|
"mute" = "none";
|
|
};
|
|
|
|
# Define custom volume control commands with key bindings
|
|
hotkeys.commands = {
|
|
"volume-up-avr" = {
|
|
name = "Volume Up AVR";
|
|
key = "Volume Up";
|
|
command = toString volumeUpScript;
|
|
};
|
|
|
|
"volume-down-avr" = {
|
|
name = "Volume Down AVR";
|
|
key = "Volume Down";
|
|
command = toString volumeDownScript;
|
|
};
|
|
|
|
"volume-mute-avr" = {
|
|
name = "Mute Toggle AVR";
|
|
key = "Volume Mute";
|
|
command = toString volumeMuteScript;
|
|
};
|
|
};
|
|
|
|
# KDE Settings customization
|
|
configFile = {
|
|
# Session restore settings
|
|
"ksmserverrc"."General"."loginMode" = "emptySession";
|
|
|
|
# Screen locking settings
|
|
"kscreenlockerrc"."Daemon"."Autolock" = false;
|
|
"kscreenlockerrc"."Daemon"."LockOnResume" = false;
|
|
|
|
# Theme settings
|
|
"kdeglobals"."KDE"."LookAndFeelPackage" = "org.kde.breezedark.desktop";
|
|
};
|
|
};
|
|
};
|
|
}
|