From a89f27b448809afc11e173877157250ee4e6d762 Mon Sep 17 00:00:00 2001 From: yunfachi Date: Tue, 12 Mar 2024 10:03:42 +0300 Subject: [PATCH 1/2] uni-sync: init at 0.2.0 --- pkgs/by-name/un/uni-sync/config_path.patch | 38 +++++++++++++++++++ .../ignore_read-only_filesystem.patch | 14 +++++++ pkgs/by-name/un/uni-sync/package.nix | 35 +++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 pkgs/by-name/un/uni-sync/config_path.patch create mode 100644 pkgs/by-name/un/uni-sync/ignore_read-only_filesystem.patch create mode 100644 pkgs/by-name/un/uni-sync/package.nix diff --git a/pkgs/by-name/un/uni-sync/config_path.patch b/pkgs/by-name/un/uni-sync/config_path.patch new file mode 100644 index 000000000000..c59bf80125ae --- /dev/null +++ b/pkgs/by-name/un/uni-sync/config_path.patch @@ -0,0 +1,38 @@ +diff --git a/src/main.rs b/src/main.rs +index 357a33b..7073497 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -1,4 +1,4 @@ +-use std::env; ++use std::path::PathBuf; + + mod devices; + +@@ -8,12 +8,23 @@ fn main() -> Result<(), std::io::Error> { + configs: vec![] + }; + +- let mut config_path = env::current_exe()?; +- config_path.pop(); +- config_path.push("uni-sync.json"); ++ let mut config_path = PathBuf::from("/etc/uni-sync/uni-sync.json"); + + if !config_path.exists() { +- std::fs::write(&config_path, serde_json::to_string_pretty(&configs).unwrap())?; ++ match std::fs::create_dir_all(config_path.parent().unwrap()) { ++ Ok(result) => result, ++ Err(_) => { ++ println!("Please run uni-sync with elevated permissions."); ++ std::process::exit(0); ++ } ++ }; ++ match std::fs::write(&config_path, serde_json::to_string_pretty(&configs).unwrap()) { ++ Ok(result) => result, ++ Err(_) => { ++ println!("Please run uni-sync with elevated permissions."); ++ std::process::exit(0); ++ } ++ }; + } + + let config_content = std::fs::read_to_string(&config_path).unwrap(); diff --git a/pkgs/by-name/un/uni-sync/ignore_read-only_filesystem.patch b/pkgs/by-name/un/uni-sync/ignore_read-only_filesystem.patch new file mode 100644 index 000000000000..3a0837d1d224 --- /dev/null +++ b/pkgs/by-name/un/uni-sync/ignore_read-only_filesystem.patch @@ -0,0 +1,14 @@ +diff --git a/src/main.rs b/src/main.rs +index f07cc64..357a33b 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -20,7 +20,7 @@ fn main() -> Result<(), std::io::Error> { + configs = serde_json::from_str::(&config_content).unwrap(); + + let new_configs = devices::run(configs); +- std::fs::write(&config_path, serde_json::to_string_pretty(&new_configs).unwrap())?; ++ std::fs::write(&config_path, serde_json::to_string_pretty(&new_configs).unwrap()); + + Ok(()) + } +\ No newline at end of file diff --git a/pkgs/by-name/un/uni-sync/package.nix b/pkgs/by-name/un/uni-sync/package.nix new file mode 100644 index 000000000000..6124e621dfb9 --- /dev/null +++ b/pkgs/by-name/un/uni-sync/package.nix @@ -0,0 +1,35 @@ +{ lib +, fetchFromGitHub +, rustPlatform +, pkg-config +, libudev-zero +}: +rustPlatform.buildRustPackage rec { + pname = "uni-sync"; + version = "0.2.0"; + + src = fetchFromGitHub { + owner = "EightB1ts"; + repo = pname; + rev = "ca349942c06fabcc028ce24e79fc6ce7c758452b"; + hash = "sha256-K2zX3rKtTaKO6q76xlxX+rDLL0gEsJ2l8x/s1vsp+ZQ="; + }; + + nativeBuildInputs = [ pkg-config ]; + buildInputs = [ libudev-zero ]; + + patches = [ + ./config_path.patch + ./ignore_read-only_filesystem.patch + ]; + + cargoHash = "sha256-DdmjP0h15cXkHJZxvOcINgoZ/EhTgu/7iYb+bgsIXxU="; + + meta = with lib; { + description = "A synchronization tool for Lian Li Uni Controllers"; + homepage = "https://github.com/EightB1ts/uni-sync"; + license = licenses.mit; + maintainers = with maintainers; [ yunfachi ]; + mainProgram = "uni-sync"; + }; +} From 05901fbaec6e00f9841f62da4bbd72b68096f763 Mon Sep 17 00:00:00 2001 From: yunfachi Date: Tue, 12 Mar 2024 18:03:59 +0300 Subject: [PATCH 2/2] nixos/uni-sync: init --- .../manual/release-notes/rl-2405.section.md | 2 + nixos/modules/hardware/uni-sync.nix | 117 ++++++++++++++++++ nixos/modules/module-list.nix | 1 + 3 files changed, 120 insertions(+) create mode 100644 nixos/modules/hardware/uni-sync.nix diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 0905337de94d..60e304f3b385 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -113,6 +113,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Mealie](https://nightly.mealie.io/), a self-hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in NuxtJS for a pleasant user experience for the whole family. Available as [services.mealie](#opt-services.mealie.enable) +- [Uni-Sync](https://github.com/EightB1ts/uni-sync), a synchronization tool for Lian Li Uni Controllers. Available as [hardware.uni-sync](#opt-hardware.uni-sync.enable) + ## Backward Incompatibilities {#sec-release-24.05-incompatibilities} diff --git a/nixos/modules/hardware/uni-sync.nix b/nixos/modules/hardware/uni-sync.nix new file mode 100644 index 000000000000..69411619bc94 --- /dev/null +++ b/nixos/modules/hardware/uni-sync.nix @@ -0,0 +1,117 @@ +{ config +, lib +, pkgs +, ... +}: +with lib; let + cfg = config.hardware.uni-sync; +in +{ + meta.maintainers = with maintainers; [ yunfachi ]; + + options.hardware.uni-sync = { + enable = mkEnableOption (mdDoc "udev rules and software for Lian Li Uni Controllers"); + package = mkPackageOption pkgs "uni-sync" { }; + + devices = mkOption { + default = [ ]; + example = literalExpression '' + [ + { + device_id = "VID:1111/PID:11111/SN:1111111111"; + sync_rgb = true; + channels = [ + { + mode = "PWM"; + } + { + mode = "Manual"; + speed = 100; + } + { + mode = "Manual"; + speed = 54; + } + { + mode = "Manual"; + speed = 0; + } + ]; + } + { + device_id = "VID:1010/PID:10101/SN:1010101010"; + sync_rgb = false; + channels = [ + { + mode = "Manual"; + speed = 0; + } + ]; + } + ] + ''; + description = mdDoc "List of controllers with their configurations."; + type = types.listOf (types.submodule { + options = { + device_id = mkOption { + type = types.str; + example = "VID:1111/PID:11111/SN:1111111111"; + description = mdDoc "Unique device ID displayed at each startup."; + }; + sync_rgb = mkOption { + type = types.bool; + default = false; + example = true; + description = mdDoc "Enable ARGB header sync."; + }; + channels = mkOption { + default = [ ]; + example = literalExpression '' + [ + { + mode = "PWM"; + } + { + mode = "Manual"; + speed = 100; + } + { + mode = "Manual"; + speed = 54; + } + { + mode = "Manual"; + speed = 0; + } + ] + ''; + description = mdDoc "List of channels connected to the controller."; + type = types.listOf (types.submodule { + options = { + mode = mkOption { + type = types.enum [ "Manual" "PWM" ]; + default = "Manual"; + example = "PWM"; + description = mdDoc "\"PWM\" to enable PWM sync. \"Manual\" to set speed."; + }; + speed = mkOption { + type = types.int; + default = "50"; + example = "100"; + description = mdDoc "Fan speed as percentage (clamped between 0 and 100)."; + }; + }; + }); + }; + }; + }); + }; + }; + + config = mkIf cfg.enable { + environment.etc."uni-sync/uni-sync.json".text = mkIf (cfg.devices != [ ]) (builtins.toJSON { configs = cfg.devices; }); + + environment.systemPackages = [ cfg.package ]; + services.udev.packages = [ cfg.package ]; + }; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 41e369ac1c65..b0b188f98387 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -98,6 +98,7 @@ ./hardware/tuxedo-keyboard.nix ./hardware/ubertooth.nix ./hardware/uinput.nix + ./hardware/uni-sync.nix ./hardware/usb-modeswitch.nix ./hardware/usb-storage.nix ./hardware/video/amdgpu-pro.nix