summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--50-docking-station.rules4
-rw-r--r--Makefile17
-rw-r--r--dock-action.py93
-rw-r--r--dock-action.sh8
4 files changed, 108 insertions, 14 deletions
diff --git a/50-docking-station.rules b/50-docking-station.rules
index 18c70f5..06021dd 100644
--- a/50-docking-station.rules
+++ b/50-docking-station.rules
@@ -1,2 +1,2 @@
-ACTION=="add", SUBSYSTEM=="net", ATTRS{addr_assign_type}=="0", ATTRS{addr_len}=="6", ATTRS{address}=="ac:91:a1:fe:97:bf" RUN+="/home/eddy/projects/arch-dock/dock-action.sh connected"
-ACTION=="remove", SUBSYSTEM=="net", ENV{ID_NET_NAME_MAC}=="enxac91a1fe97bf" RUN+="/home/eddy/projects/arch-dock/dock-action.sh disconnected"
+ACTION=="add", SUBSYSTEM=="net", ATTRS{addr_assign_type}=="0", ATTRS{addr_len}=="6", ATTRS{address}=="ac:91:a1:fe:97:bf" RUN+="/usr/local/bin/dock-action.py connected work-desk"
+ACTION=="remove", SUBSYSTEM=="net", ENV{ID_NET_NAME_MAC}=="enxac91a1fe97bf" RUN+="/usr/local/bin/dock-action.py disconnected work-desk"
diff --git a/Makefile b/Makefile
index e858a74..2511f0a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,23 @@
UDEV_RULE_DIR := /etc/udev/rules.d
RULES_FILE := 50-docking-station.rules
-$(UDEV_RULE_DIR)/$(RULES_FILE): $(RULES_FILE)
- @echo "Installing udev rules (requires root access)"
- sudo install --owner=root --group=root --mode=644 -t $(UDEV_RULE_DIR) $(RULES_FILE)
+SCRIPT_DIR := /usr/local/bin
+SCRIPT := dock-action.py
-install: $(UDEV_RULE_DIR)/$(RULES_FILE)
+install: $(UDEV_RULE_DIR)/$(RULES_FILE) $(SCRIPT_DIR)/$(SCRIPT)
uninstall:
@echo "Removing udev rules (requires root access)"
sudo rm "$(UDEV_RULE_DIR)/$(RULES_FILE)"
+ @echo "Removing script (requires root access)"
+ sudo rm "$(SCRIPT_DIR)/$(SCRIPT)"
+
+$(UDEV_RULE_DIR)/$(RULES_FILE): $(RULES_FILE)
+ @echo "Installing udev rules (requires root access)"
+ sudo install --owner=root --group=root --mode=644 -t $(UDEV_RULE_DIR) $(RULES_FILE)
+
+$(SCRIPT_DIR)/$(SCRIPT): $(SCRIPT)
+ @echo "Installing script (requires root access)"
+ sudo install --owner=root --group=root --mode=755 -t $(SCRIPT_DIR) $(SCRIPT)
.PHONY: install uninstall
diff --git a/dock-action.py b/dock-action.py
new file mode 100644
index 0000000..454cab8
--- /dev/null
+++ b/dock-action.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+import logging
+import argparse
+import os
+from subprocess import run
+
+DRY_RUN = False
+WLAN_ADAPTER = "wlp1s0"
+DEVICES = {
+ "work-desk" : {
+ "displays" : {
+ "DisplayPort-2" : "auto",
+ "eDP" : "off"
+ },
+ "mac_address" : "ac:91:a1:fe:97:bf"
+ }
+}
+
+def get_adapter_name(mac_address: str) -> str:
+ import json
+ interfaces = json.loads(run(["ip", "-j", "link"], capture_output=True).stdout)
+ matches = [i for i in interfaces if i["address"].lower() == mac_address]
+ if len(matches) > 0:
+ return matches[0]["ifname"]
+ else:
+ return None
+
+def do(command: list[str]) -> None:
+ if DRY_RUN:
+ logging.info(f"Run command: {command}")
+ else:
+ result = run(command, capture_output=True)
+ if result.returncode != 0:
+ logging.error(f"Command returned {result.returncode}: {' '.join(command)}")
+ logging.error(result.stdout)
+ logging.error(result.stderr)
+
+def connected(device_name: str) -> None:
+ logging.info(f"Connected notification for {device_name}")
+
+ if device_name not in DEVICES:
+ logging.info(f"Unregistered device {device_name}, ignoring")
+ return
+ device = DEVICES[device_name]
+
+ eth_adapter = get_adapter_name(device["mac_address"])
+ if eth_adapter is None:
+ logging.error("No network adapter found, exiting")
+ return
+
+ logging.debug("Disabling wireless adapter")
+ do(["ip", "link", "set", WLAN_ADAPTER, "down"])
+
+ logging.debug("Enabling ethernet adapter")
+ do(["ip", "link", "set", eth_adapter, "up"])
+
+ logging.debug("Configuring monitors")
+ xrandr_args = ["xrandr"]
+ for display, mode in device["displays"].items():
+ xrandr_args.append("--output")
+ xrandr_args.append(display)
+ xrandr_args.append(f"--{mode}")
+ do(xrandr_args)
+
+def disconnected(device_name: str) -> None:
+ logging.info(f"Disconnected notification for {device_name}")
+
+ logging.debug("Enabling wireless adapter")
+ do(["ip", "link", "set", WLAN_ADAPTER, "up"])
+
+ logging.debug("Configuring monitors")
+ do(["xrandr", "--auto"])
+
+def main() -> None:
+ #logging.basicConfig(filename="/home/eddy/dock.log", encoding="utf-8", level=logging.DEBUG)
+ os.environ["DISPLAY"] = ":0"
+ os.environ["XAUTHORITY"] = "/home/eddy/.Xauthority"
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("action")
+ parser.add_argument("device")
+ args = parser.parse_args()
+
+ if args.action == "connected":
+ connected(args.device)
+ elif args.action == "disconnected":
+ disconnected(args.device)
+
+ logging.info("Done")
+
+if __name__ == "__main__":
+ main()
diff --git a/dock-action.sh b/dock-action.sh
deleted file mode 100644
index 3b93398..0000000
--- a/dock-action.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/bash
-
-if [ "$1" = "connected" ]; then
- echo "Dock connected" >> /home/eddy/dock.log
-elif [ "$1" = "disconnected" ]; then
- echo "Dock disconnected" >> /home/eddy/dock.log
-fi
-