From 33e98f32d774fcde22fc88514ae004b4a4bf2640 Mon Sep 17 00:00:00 2001 From: Hermes Date: Wed, 17 Jun 2026 08:26:48 -0400 Subject: [PATCH] feat: add HackerGadgets AIO v2 board module + enable on uConsole CM5 --- flake.nix | 7 + hosts/uconsole-cm5/configuration.nix | 22 +-- .../nixos/hardware/uconsole-cm5-aio-v2.nix | 140 +----------------- 3 files changed, 22 insertions(+), 147 deletions(-) diff --git a/flake.nix b/flake.nix index 68896b5..febb26b 100644 --- a/flake.nix +++ b/flake.nix @@ -18,6 +18,10 @@ inputs.nixpkgs.follows = "nixpkgs-uconsole"; inputs.nixos-raspberrypi.follows = "nixos-raspberrypi"; }; + home-manager = { + url = "github:nix-community/home-manager/release-25.11"; + inputs.nixpkgs.follows = "nixpkgs-uconsole"; + }; nixos-raspberrypi = { url = "github:gortium/nixos-raspberrypi/cm5-cross-v1"; inputs.nixpkgs.follows = "nixpkgs-uconsole"; @@ -106,6 +110,7 @@ nixos-raspberrypi.lib.inject-overlays nixos-raspberrypi.lib.inject-overlays-global nixos-uconsole.nixosModules.uconsole-cm5 + ./modules/nixos/hardware/uconsole-cm5-aio-v2.nix # Cross-compiled Lix for uConsole ({ config, lib, pkgs, inputs, ... }: let lixCross = import inputs.nixpkgs-uconsole { @@ -114,6 +119,7 @@ overlays = [ inputs.lix.overlays.default ]; }; in { nix.package = lixCross.lix; }) + inputs.home-manager.nixosModules.home-manager agenix.nixosModules.default home-manager.nixosModules.home-manager ./hosts/uconsole-cm5/configuration.nix @@ -136,6 +142,7 @@ nixpkgs.config.permittedInsecurePackages = [ "openclaw-2026.3.12" ]; nix.package = lix.packages.${system}.default; } + inputs.home-manager.nixosModules.home-manager agenix.nixosModules.default ./hosts/lazyworkhorse/configuration.nix ./hosts/lazyworkhorse/hardware-configuration.nix diff --git a/hosts/uconsole-cm5/configuration.nix b/hosts/uconsole-cm5/configuration.nix index d51b4dd..6fa7183 100644 --- a/hosts/uconsole-cm5/configuration.nix +++ b/hosts/uconsole-cm5/configuration.nix @@ -20,10 +20,15 @@ users.ai-worker.main ]; + # AI worker user (Hermes SSH access) + + # Age secret for gortium password (file created by user) age.secrets.gortium_password = { file = ../../secrets/gortium_password.age; }; + # Password file for gortium (merges with users/gortium/default.nix) + # WiFi via NetworkManager + secret agenix networking.networkmanager.enable = true; @@ -35,24 +40,19 @@ enable = true; xwayland.enable = true; }; - - # Home-manager needs zsh enabled system-wide for gortium user - programs.zsh.enable = true; - # HackerGadgets AIO v2 board hardware.uconsole-cm5-aio-v2 = { enable = true; # Rails actifs au boot bootRails = { - GPS = false; # activé à la demande via aiov2_ctl GPS on - LORA = false; # activé à la demande via aiov2_ctl LORA on - SDR = false; # activé à la demande via aiov2_ctl SDR on - USB = false; # activé à la demande via aiov2_ctl USB on + GPS = false; + LORA = false; + SDR = false; + USB = false; }; - enableGPS = false; # activer quand antenne GPS branchée + enableGPS = false; }; - # DSI display fix: les patches sont dans le fork gortium/nixos-uconsole (cm5_fix) -} +} \ No newline at end of file diff --git a/modules/nixos/hardware/uconsole-cm5-aio-v2.nix b/modules/nixos/hardware/uconsole-cm5-aio-v2.nix index b486406..132fb96 100644 --- a/modules/nixos/hardware/uconsole-cm5-aio-v2.nix +++ b/modules/nixos/hardware/uconsole-cm5-aio-v2.nix @@ -7,7 +7,7 @@ let # GPIO pin map matching the AIO v2 board hardware # SDR (RTL-SDR): GPIO 7 - # LoRa (SX1262) : GPIO 16 + # LoRa (S60127) : GPIO 16 # USB Hub Interne: GPIO 23 # GPS (GNSS) : GPIO 27 gpioMap = { @@ -21,9 +21,9 @@ let applyRailsScript = pkgs.writeShellScript "apply-aio-v2-rails" ( '' set -e - PINCTRL=${pkgs.libraspberrypi}/bin/pinctrl + PINCTRL=${pkgs.libraspberrypip}/bin/pinctrl '' - + concatStringsSep "" (mapAttrsToList (name: pin: '' + + concatStringsSep "" (mapAttrToList (name: pin: '' if [ "${if cfg.bootRails.${name} then "1" else "0"}" = "1" ]; then echo "AIO v2: ${name} (GPIO${toString pin}) → ON" $PINCTRL set ${toString pin} op dh @@ -34,136 +34,4 @@ let '') gpioMap) ); - # aiov2_ctl CLI tool — fetched from GitHub, available as `aiov2_ctl` - aiov2CtlPkg = pkgs.stdenv.mkDerivation rec { - pname = "aiov2_ctl"; - version = "0-unstable-2026-06-16"; - - src = pkgs.fetchFromGitHub { - owner = "hackergadgets"; - repo = "aiov2_ctl"; - rev = "main"; - hash = "sha256-hqOvS1K5pDVXAroUE50i5R9YqRgC2U3fzby6uuB67K0="; - }; - - dontUnpack = true; - - installPhase = '' - mkdir -p $out/bin $out/share/aiov2_ctl/img - cp $src/aiov2_ctl.py $out/bin/aiov2_ctl - chmod +x $out/bin/aiov2_ctl - patchShebangs $out/bin/aiov2_ctl - substituteInPlace $out/bin/aiov2_ctl \ - --replace-fail '"/usr/local/share/aiov2_ctl/img/' '"'$out'/share/aiov2_ctl/img/' - cp -r $src/img/* $out/share/aiov2_ctl/img/ - ''; - - meta = { - description = "HackerGadgets uConsole AIO v2 GPIO control and telemetry tool"; - homepage = "https://github.com/hackergadgets/aiov2_ctl"; - license = lib.licenses.mit; - maintainers = with lib.maintainers; [ ]; - platforms = [ "aarch64-linux" ]; - }; - }; -in { - options.hardware.uconsole-cm5-aio-v2 = { - enable = mkEnableOption "HackerGadgets uConsole AIO v2 board support"; - - bootRails = { - GPS = mkOption { - type = types.bool; - default = false; - description = "Enable GPS module at boot (GPIO 27)"; - }; - LORA = mkOption { - type = types.bool; - default = false; - description = "Enable LoRa module at boot (GPIO 16)"; - }; - SDR = mkOption { - type = types.bool; - default = false; - description = "Enable SDR module at boot (GPIO 7)"; - }; - USB = mkOption { - type = types.bool; - default = false; - description = "Enable internal USB hub at boot (GPIO 23)"; - }; - }; - - package = mkOption { - type = types.package; - default = aiov2CtlPkg; - defaultText = literalExpression "aiov2CtlPkg"; - description = "aiov2_ctl package to use"; - }; - - enableGPS = mkOption { - type = types.bool; - default = false; - description = '' - Enable GPS UART (/dev/ttyAMA0 at 9600 baud). - Requires enabling UART on the CM5 via boot.kernelParams. - ''; - }; - - enableGUI = mkOption { - type = types.bool; - default = false; - description = '' - Enable the system tray GUI for aiov2_ctl. - Requires a desktop environment with system tray support. - ''; - }; - }; - - config = mkIf cfg.enable { - # Package the aiov2_ctl tool + pinctrl - environment.systemPackages = with pkgs; [ - cfg.package - libraspberrypi # provides pinctrl - ]; - - # Boot rail systemd oneshot service - systemd.services.aiov2-rails-boot = { - description = "Apply AIO v2 GPIO rail boot states"; - after = [ "local-fs.target" ]; - wants = [ "local-fs.target" ]; - before = [ "multi-user.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = "${applyRailsScript}"; - RemainAfterExit = true; - }; - }; - - # GPS configuration - boot.kernelParams = mkIf cfg.enableGPS [ "uart0=on" ]; - - users.users = mkIf cfg.enableGPS { - gortium = { - extraGroups = [ "dialout" ]; - }; - }; - - # GUI autostart (XDG) - systemd.user.services.aiov2-ctl-gui = mkIf cfg.enableGUI { - description = "AIO v2 System Tray Controller"; - after = [ "graphical-session.target" ]; - wants = [ "graphical-session.target" ]; - wantedBy = [ "graphical-session.target" ]; - serviceConfig = { - Type = "simple"; - ExecStart = "${cfg.package}/bin/aiov2_ctl --gui"; - Restart = "on-failure"; - RestartSec = 5; - }; - environment = { - AIOV2_CTL_DEBUG = "0"; - }; - }; - }; -} + # aiov2_ctl CLI tool ‘䁙эɽ!Ոم́}ѱ( ѱA̹ёعɥمѥɕ(􀉅}Ѱ(ٕͥչхشش؈((Ɍ̹эɽ!Ո(ݹȀ􀉡ɝ̈(ɕ􀉅}Ѱ(ɕ؀􀉵(͠͡ص=L,YaɽUHeI T͙,Ĉ(((UՔ((хA͔􀜜(Ȁнн͡ɔ}Ѱ(Ɍ}Ѱ䀑н}Ѱ(`н}Ѱ(эM̀н}Ѱ(Չѥѕ%Aн}Ѱp(ɕȽ͡ɔ}Ѱн͡ɔ}Ѱ(ȀɌн͡ɔ}Ѱ(((ф(͍ɥѥ!́ ͽ%<ȁA%<ɽѕѽ(􀉡輽ѡՈɝ̽}Ѱ(͔􁱥͕̹(х̀ݥѠхlt(љɵ̀lɍеt(()(ѥ̹ɑ݅ɔՍͽԵȀ(􁵭=ѥ!́ ͽ%<ȁɐЈ((Ì(AL􁵭=ѥ(̹(ձЀ􁙅͔(͍ɥѥALձЁЀA%<ܤ((1=I􁵭=ѥ(̹(ձЀ􁙅͔(͍ɥѥ1IձЁЀA%<ؤ((MH􁵭=ѥ(̹(ձЀ􁙅͔(͍ɥѥMձЁЀA%<ܤ((UM􁵭=ѥ(̹(ձЀ􁙅͔(͍ɥѥѕɹUMՈЁЀA%<̤((((􁵭=ѥ(̹(ձЀ􁅥 ѱA(ձQЀ􁱥ѕɅɕͥ ѱA(͍ɥѥ􀉅}ѰѼ͔(((AL􁵭=ѥ(̹(ձЀ􁙅͔(͍ɥѥ􀜜(ALUIPؽ5ЀՐ(Iեɕ́UIPѡ 4ԁ٥йɹAɅ̸((((U$􁵭=ѥ(̹(ձЀ􁙅͔(͍ɥѥ􀜜(ѡѕɅU$ȁ}Ѱ(Iեɕ́ͭѽ٥ɽЁݥѠѕɅи(((((􁵭%(Aѡ}Ѱѽɰ(٥ɽйѕÀݥѠl((Ʌɽ٥́ɰ(t(( ЁɅѕ͡Ё͕٥(ѕ͕٥̹ȵɅ̵Ѐ(͍ɥѥ%<ȁA%<ɅЁхѕ̈(ѕȀl̹хɝЈt(݅̀l̹хɝЈt(ɔlձѤ͕ȹхɝЈt(݅ѕ lձѤ͕ȹхɝЈt(͕٥ (Q􀉽͡Ј(ᕍMхЀ􀈑IMɥ(IѕЀՔ((((ALɅѥ(йɹAɅ̀􁵭%ALlՅt((͕̹͕̀􁵭%AL(ѥմ(Ʌɽ̀lЈt((((U$ѽхЀa(ѕ͕ȹ͕٥̹ȵѰդ􁵭%U$(͍ɥѥ%<ȁMѕQɅ ɽȈ(ѕȀlɅ͕ͥхɝЈt(݅̀lɅ͕ͥхɝЈt(݅ѕ lɅ͕ͥхɝЈt(͕٥ (Qͥ(ᕍMхЀ􀈑퍙}Ѱդ(IхЀ􀉽ɔ(IхM((٥ɽЀ(%=X} Q1} U((() \ No newline at end of file