diff --git a/flake.lock b/flake.lock index 7811a76..c5f03c7 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1701189068, - "narHash": "sha256-Z84Km4ILllusI9IPI9qFRKN4Ss5893Ntbp1TcMCFIds=", + "lastModified": 1701222237, + "narHash": "sha256-e2oXDUi3SO6dz2s0bElojErRcblOGYwMnpcJE93lWTI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6fc4c1c40c98de86565acdb3fe43c6ba3efb3115", + "rev": "32d235daa928ec3d31ec3f601486d38b580e809d", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 701cfe4..e1cd364 100644 --- a/flake.nix +++ b/flake.nix @@ -22,14 +22,15 @@ formatter = pkgs.alejandra; packages = { - default = self'.packages.pi-air-quality-monitor; - pi-air-quality-monitor = pkgs.callPackage ./nix/default.nix {}; + default = self'.packages.air-quality-monitor; + air-quality-monitor = pkgs.callPackage ./nix/packages/air-quality-monitor.nix {inherit self;}; + dummy-serial = pkgs.callPackage ./nix/packages/dummy-serial.nix {}; }; devShells = { - default = self'.packages.pi-air-quality-monitor; - pi-air-quality-monitor = pkgs.mkShell { - inputsFrom = self'.packages.pi-air-quality-monitor.pythonPath; + default = self'.devShells.air-quality-monitor; + air-quality-monitor = pkgs.mkShell { + inputsFrom = self'.packages.air-quality-monitor.pythonPath; }; }; }; diff --git a/nix/module.nix b/nix/module.nix index 1bb8cdc..2abb938 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -12,7 +12,7 @@ in { enable = mkEnableOption "pi-air-quality-monitor"; package = mkOption { type = types.package; - default = self.packages.${pkgs.system}.pi-air-quality-monitor; + default = self.packages.${pkgs.system}.air-quality-monitor; }; openFirewall = mkOption { diff --git a/nix/packages/air-quality-monitor.nix b/nix/packages/air-quality-monitor.nix new file mode 100644 index 0000000..f3a8464 --- /dev/null +++ b/nix/packages/air-quality-monitor.nix @@ -0,0 +1,63 @@ +{ + self, + lib, + python3Packages, + makeWrapper, + python3, + ... +}: let + pname = "pi_air_quality_monitor"; + version = "0.0.1"; +in + python3Packages.buildPythonApplication { + inherit pname version; + format = "other"; + + src = self + /src; + + pythonPath = with python3Packages; [ + pyserial + flask + redis + ipython + apscheduler + flask-cors + ( + buildPythonPackage rec { + pname = "python-aqi"; + version = "0.6.1"; + src = fetchPypi { + inherit pname version; + hash = "sha256-FBoDoP7UiIDchwbKV7A/MPqRq2DpMwR0v5yaj7m5YCA="; + }; + } + ) + ]; + + nativeBuildInputs = [makeWrapper]; + installFlags = ["prefix=$(out/bin)"]; + + postUnpack = '' + mkdir -p $out/bin + cp -rvf $src/* $out + ''; + + preFixup = '' + buildPythonPath "$pythonPath" + gappsWrapperArgs+=( + --prefix PYTHONPATH : "$program_PYTHONPATH" + ) + makeWrapper ${lib.getExe python3} $out/bin/${pname} \ + --add-flags $out/app.py \ + --prefix PYTHONPATH : "$program_PYTHONPATH" \ + --chdir $out/bin + ''; + + meta = { + description = "An air quality monitoring service with a Raspberry Pi and a SDS011 sensor. "; + homepage = "https://github.com/rydercalmdown/pi_air_quality_monitor"; + mainProgram = pname; + platforms = ["aarch64-linux" "x86_64-linux"]; + maintainers = with lib.maintainers; [NotAShelf]; + }; + } diff --git a/nix/packages/dummy-serial.nix b/nix/packages/dummy-serial.nix new file mode 100644 index 0000000..ff44f54 --- /dev/null +++ b/nix/packages/dummy-serial.nix @@ -0,0 +1,30 @@ +{ + stdenv, + fetchFromGitHub, + ... +}: +stdenv.mkDerivation { + pname = "dummy-serial"; + version = "0.1.0"; + + src = fetchFromGitHub { + owner = "notashelf"; + repo = "dummy-serial"; + rev = "v0.1.0"; + hash = "sha256-+zXA5Ko8ikgkmkm1eyx2VMQQjp61osSpq4K+d9WEqq8="; + }; + + makeFlags = ["TARGET=main"]; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp -rvf main $out/bin/dummy-serial + runHook postInstall + ''; + + meta = { + description = "Create dummy serial ports through PseudoTTYs"; + mainProgram = "dummy-serial"; + }; +} diff --git a/nix/tests/checks/basic.nix b/nix/tests/checks/basic.nix index 5370156..382171b 100644 --- a/nix/tests/checks/basic.nix +++ b/nix/tests/checks/basic.nix @@ -1,9 +1,11 @@ { nixosTest, self, + self', + lib, ... }: let - serialPort = "/dev/ttyS0"; + serialPort = "/dev/pts/2"; in nixosTest { name = "basic"; @@ -50,24 +52,25 @@ in testScript = '' server.start() - server.wait_for_unit("default.target") + server.wait_for_unit("network.target") log.info("Checking if configured serial port exists") - server.succeed("ls -lah ${serialPort}") + serialPort = server.succeed("${lib.getExe self'.packages.dummy-serial} --quiet") + + if any(serialPort): + log.info("Serial port exists!") + else: + log.info("Serial port does not exist") log.info("Check if unit is running correctly") server.wait_for_unit("pi-air-quality-monitor.service") - server.succeed("systemctl status pi-air-quality-monitor.service | grep 'Active: active (running)' >&2") - server.fail("journalctl -u pi-air-quality-monitor.service | grep 'RuntimeError'") - - log.info("Showing units content") - server.succeed("systemctl status pi-air-quality-monitor.service >&2") - server.succeed("systemctl cat pi-air-quality-monitor.service >&2") + server.succeed("systemctl status pi-air-quality-monitor.service | grep 'Active: active (running)'") + server.fail("journalctl -xeu pi-air-quality-monitor.service | grep 'RuntimeError'") log.info("Checking if service is accessible locally") - server.succeed("nc -vz localhost 8080") + server.succeed("curl --fail http://localhost:8080 | grep 'Air'") client.start() - client.wait_for_unit("default.target") + client.wait_for_unit("network.target") client.succeed("nc -vz server 8080") ''; } diff --git a/nix/tests/default.nix b/nix/tests/default.nix index ce65c23..d2ab71d 100644 --- a/nix/tests/default.nix +++ b/nix/tests/default.nix @@ -19,7 +19,7 @@ packages.test = self'.checks.basic.driverInteractive; checks = { - basic = callPackage ./checks/basic.nix {inherit self;}; + basic = callPackage ./checks/basic.nix {inherit self self';}; default = self'.checks.basic; }; };