diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 5db8d13fd6562..be92434ae3488 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -22260,6 +22260,12 @@ github = "vbrandl"; githubId = 20639051; }; + vbruegge = { + email = "lina@vanbruegge.de"; + github = "vBruegge"; + githubId = 113902289; + name = "Lina van Brügge"; + }; vcanadi = { email = "vito.canadi@gmail.com"; github = "vcanadi"; diff --git a/nixos/modules/hardware/bitcraze.nix b/nixos/modules/hardware/bitcraze.nix new file mode 100644 index 0000000000000..aa93fa13db347 --- /dev/null +++ b/nixos/modules/hardware/bitcraze.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.hardware.bitcraze; +in +{ + options.hardware.bitcraze = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Bitcraze Crazyflie udev rules and ensure 'plugdev' group exists. + This is a prerequisite to using Bitcraze Crazyflie devices without being root, since Bitcraze Crazyflie USB descriptors will be owned by plugdev through udev. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + services.udev.packages = [ pkgs.bitcraze-udev-rules ]; + users.groups.plugdev = { }; + }; + + meta.maintainers = with lib.maintainers; [ + vbruegge + stargate01 + ]; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index bf9b3db4b9677..4f5d09160a33e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -48,6 +48,7 @@ ./config/zram.nix ./hardware/acpilight.nix ./hardware/all-firmware.nix + ./hardware/bitcraze.nix ./hardware/bladeRF.nix ./hardware/brillo.nix ./hardware/ckb-next.nix diff --git a/pkgs/by-name/bi/bitcraze-udev-rules/99-bitcraze.rules b/pkgs/by-name/bi/bitcraze-udev-rules/99-bitcraze.rules new file mode 100644 index 0000000000000..3b4bb7617b46e --- /dev/null +++ b/pkgs/by-name/bi/bitcraze-udev-rules/99-bitcraze.rules @@ -0,0 +1,6 @@ +# Crazyradio (normal operation) +SUBSYSTEM=="usb", ATTRS{idVendor}=="1915", ATTRS{idProduct}=="7777", MODE="0664", GROUP="plugdev" +# Bootloader +SUBSYSTEM=="usb", ATTRS{idVendor}=="1915", ATTRS{idProduct}=="0101", MODE="0664", GROUP="plugdev" +# Crazyflie (over USB) +SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0664", GROUP="plugdev" diff --git a/pkgs/by-name/bi/bitcraze-udev-rules/package.nix b/pkgs/by-name/bi/bitcraze-udev-rules/package.nix new file mode 100644 index 0000000000000..485d4dca6badd --- /dev/null +++ b/pkgs/by-name/bi/bitcraze-udev-rules/package.nix @@ -0,0 +1,31 @@ +{ + lib, + stdenvNoCC, + fetchurl, +}: + +stdenvNoCC.mkDerivation { + pname = "bitcraze-udev-rules"; + version = "0.1.23"; + + dontUnpack = true; + + installPhase = '' + runHook preInstall + + install -Dm444 ${./99-bitcraze.rules} $out/lib/udev/rules.d/99-bitcraze.rules + + runHook postInstall + ''; + + meta = with lib; { + description = "Udev rules for Bitcraze Crazyflie"; + license = licenses.gpl2; + maintainers = with maintainers; [ + vbruegge + stargate01 + ]; + platforms = platforms.linux; + homepage = "https://github.com/bitcraze/crazyflie-lib-python/blob/master/docs/installation/usb_permissions.md"; + }; +} diff --git a/pkgs/development/python-modules/cfclient/default.nix b/pkgs/development/python-modules/cfclient/default.nix new file mode 100644 index 0000000000000..6686fcc284404 --- /dev/null +++ b/pkgs/development/python-modules/cfclient/default.nix @@ -0,0 +1,92 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + pythonOlder, + cflib, + appdirs, + pyzmq, + pyqtgraph, + pyyaml, + numpy, + vispy, + pyserial, + pyqt6, + pyqt6-sip, + qasync, + packaging, + qtm, + xorg, + wrapQtAppsHook, + pythonRelaxDepsHook, + qt5, +}: + +buildPythonPackage rec { + pname = "cfclient"; + version = "2023.6"; + format = "setuptools"; + disabled = pythonOlder "3.7"; + + src = fetchFromGitHub { + owner = "bitcraze"; + repo = "crazyflie-clients-python"; + rev = version; + hash = "sha256-QQuULICE/RjhZj3GGeFJ0hFrFJJ9FphQndeqWQCf59A="; + }; + + postPatch = '' + echo '{"version": "${version}"}' > src/cfclient/version.json + ''; + + propagatedBuildInputs = [ + cflib + appdirs + pyzmq + pyqtgraph + pyyaml + numpy + vispy + pyserial + pyqt6 + pyqt6-sip + qasync + packaging + qtm + pyqtgraph + ]; + + buildInputs = [ + qt5.qtbase + xorg.libXinerama + ]; + + nativeBuildInputs = [ + wrapQtAppsHook + pythonRelaxDepsHook + ]; + + postFixup = '' + wrapQtApp $out/bin/cfclient + ''; + + pythonRelaxDeps = true; + + dontWrapQtApps = true; + + pythonImportsCheck = [ "cfclient" ]; + + doCheck = false; + + meta = with lib; { + homepage = "https://github.com/bitcraze/crazyflie-clients-python"; + description = "Host applications and library for Crazyflie written in Python"; + license = licenses.gpl2; + platforms = platforms.linux; + maintainers = with maintainers; [ + vbruegge + stargate01 + ]; + mainProgram = "cfclient"; + }; +} diff --git a/pkgs/development/python-modules/cflib/default.nix b/pkgs/development/python-modules/cflib/default.nix new file mode 100644 index 0000000000000..6c21dcdbdcb48 --- /dev/null +++ b/pkgs/development/python-modules/cflib/default.nix @@ -0,0 +1,78 @@ +{ + stdenv, + lib, + buildPythonPackage, + fetchFromGitHub, + libusb-package, + pyusb, + scipy, + numpy, + pytestCheckHook, + pyyaml, + pythonOlder, + bitcraze-udev-rules, + pythonRelaxDepsHook, +}: + +buildPythonPackage rec { + pname = "cflib"; + version = "0.1.23"; + format = "setuptools"; + disabled = pythonOlder "3.7"; + + src = fetchFromGitHub { + owner = "bitcraze"; + repo = "crazyflie-lib-python"; + rev = version; + hash = "sha256-OZQAisA9b3YIf3zEC5RlrW70h4tgCBC19/KEvle+kLY="; + }; + + propagatedBuildInputs = + [ + pyusb + scipy + numpy + libusb-package + ] + ++ lib.optionals stdenv.isLinux [ + bitcraze-udev-rules + ]; + + nativeBuildInputs = [ + pythonRelaxDepsHook + ]; + + pythonRelaxDeps = true; + + nativeCheckInputs = [ + pytestCheckHook + ]; + + checkInputs = [ + pyyaml + ]; + + disabledTestPaths = [ + # Disable tests which require a physical device connection + "sys_test/single_cf_grounded/test_bootloader.py" + "sys_test/single_cf_grounded/test_link.py" + "sys_test/single_cf_grounded/test_power_switch.py" + "sys_test/swarm_test_rig/test_connection.py" + "sys_test/swarm_test_rig/test_logging.py" + "sys_test/swarm_test_rig/test_memory_map.py" + "sys_test/swarm_test_rig/test_response_time.py" + ]; + + pythonImportsCheck = [ "cflib" ]; + + meta = with lib; { + homepage = "https://github.com/bitcraze/crazyflie-lib-python"; + description = "Python library to communicate with Crazyflie"; + license = licenses.gpl2; + platforms = platforms.linux; + maintainers = with maintainers; [ + vbruegge + stargate01 + ]; + }; +} diff --git a/pkgs/development/python-modules/libusb-package/default.nix b/pkgs/development/python-modules/libusb-package/default.nix new file mode 100644 index 0000000000000..b587fc701df92 --- /dev/null +++ b/pkgs/development/python-modules/libusb-package/default.nix @@ -0,0 +1,75 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + libusb1, + pytestCheckHook, + python, + pythonOlder, + setuptools-scm, + importlib-resources, + pyusb, +}: + +buildPythonPackage rec { + pname = "libusb-package"; + version = "1.0.26.2"; + format = "setuptools"; + disabled = pythonOlder "3.7"; + + src = fetchFromGitHub { + owner = "pyocd"; + repo = "libusb-package"; + rev = "v${version}"; + hash = "sha256-bM+v3eeQQHiBKsFky51KdDYlRjFzykQFkuFKkluqkjY="; + }; + + patches = [ ./fix-pytest.patch ]; + + # Replace the setup to not build libusb + postPatch = '' + cp -f ${./setup.py} setup.py + ''; + + SETUPTOOLS_SCM_PRETEND_VERSION = version; + buildInputs = [ + setuptools-scm + ]; + + propagatedBuildInputs = [ + importlib-resources + ]; + + propagatedNativeBuildInputs = [ + libusb1 + ]; + + # Symlink the system libusb instead of building it + postInstall = '' + ln -fs "${libusb1}/lib/libusb-1.0.so" "$out/${python.sitePackages}/libusb_package/libusb-1.0.so" + ''; + + nativeCheckInputs = [ + pytestCheckHook + libusb1 + ]; + + checkInputs = [ + pyusb + ]; + + pytestFlagsArray = [ "test.py" ]; + + pythonImportsCheck = [ "libusb_package" ]; + + meta = with lib; { + homepage = "https://github.com/pyocd/libusb-package"; + description = "Packaged libusb shared libraries for Python"; + license = licenses.asl20; + platforms = platforms.linux; + maintainers = with maintainers; [ + vbruegge + stargate01 + ]; + }; +} diff --git a/pkgs/development/python-modules/libusb-package/fix-pytest.patch b/pkgs/development/python-modules/libusb-package/fix-pytest.patch new file mode 100644 index 0000000000000..d5b4e801e9e47 --- /dev/null +++ b/pkgs/development/python-modules/libusb-package/fix-pytest.patch @@ -0,0 +1,20 @@ +diff --git a/test.py b/test.py +index 93d2603e0440..078246bee35e 100644 +--- a/test.py ++++ b/test.py +@@ -5,7 +5,7 @@ import libusb_package + import usb.core + import usb.backend.libusb1 + +-def main(): ++def test_main(): + # Test get_library_path(). + path = libusb_package.get_library_path() + print(f"Path to included library: {path}") +@@ -29,6 +29,4 @@ def main(): + except Exception as err: + print(f"{dev.idVendor:04x}:{dev.idProduct:04x}: error reading strings ({err})") + +-if __name__ == "__main__": +- main() + diff --git a/pkgs/development/python-modules/libusb-package/setup.py b/pkgs/development/python-modules/libusb-package/setup.py new file mode 100644 index 0000000000000..b19a8385ff737 --- /dev/null +++ b/pkgs/development/python-modules/libusb-package/setup.py @@ -0,0 +1,6 @@ +from setuptools import setup + +setup( + name='libusb_package', + packages=['libusb_package'] +) diff --git a/pkgs/development/python-modules/qtm/default.nix b/pkgs/development/python-modules/qtm/default.nix new file mode 100644 index 0000000000000..d586e933a0c59 --- /dev/null +++ b/pkgs/development/python-modules/qtm/default.nix @@ -0,0 +1,51 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + pythonOlder, + pythonAtLeast, + pytestCheckHook, + pytest-asyncio, + pytest-mock, +}: + +buildPythonPackage rec { + pname = "qtm"; + version = "2.1.2"; + format = "setuptools"; + disabled = pythonOlder "3.7"; + + src = fetchFromGitHub { + owner = "qualisys"; + repo = "qualisys_python_sdk"; + rev = "v${version}"; + hash = "sha256-cfQV4s0hXq7kxP5AJAskdR+JJzlpCObTDZ4qLOZt0/o="; + }; + + nativeCheckInputs = [ + pytestCheckHook + ]; + + checkInputs = [ + pytest-asyncio + pytest-mock + ]; + + disabledTestPaths = lib.optionals (pythonAtLeast "3.11") [ + # This test fails with Python 3.11+, but the library is still compatible + "test/qtmprotocol_test.py" + ]; + + pythonImportsCheck = [ "qtm" ]; + + meta = with lib; { + homepage = "https://github.com/qualisys/qualisys_python_sdk"; + description = "Python implementation of the real-time protocol for Qualisys Track Manager (legacy version)"; + license = licenses.mit; + platforms = platforms.linux; + maintainers = with maintainers; [ + vbruegge + stargate01 + ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index d5e20d0a6b651..f9d0045df87c5 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -15786,6 +15786,8 @@ with pkgs; cauwugo = callPackage ../development/tools/rust/cauwugo { }; + cfclient = with python3Packages; toPythonApplication cfclient; + critcmp = callPackage ../development/tools/rust/critcmp { }; devspace = callPackage ../development/tools/misc/devspace { }; @@ -26910,8 +26912,6 @@ with pkgs; bibata-cursors-translucent = callPackage ../data/icons/bibata-cursors/translucent.nix { }; - apple-cursor = callPackage ../data/icons/apple-cursor { }; - blackbird = callPackage ../data/themes/blackbird { }; blackout = callPackage ../data/fonts/blackout { }; diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 7b7ed5e1154f3..4da5d3f3e08f9 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -2136,6 +2136,10 @@ self: super: with self; { cf-xarray = callPackage ../development/python-modules/cf-xarray { }; + cfclient = callPackage ../development/python-modules/cfclient { + inherit (pkgs.libsForQt5) wrapQtAppsHook; + }; + cffconvert = callPackage ../development/python-modules/cffconvert { }; cffi = callPackage ../development/python-modules/cffi { }; @@ -2148,6 +2152,8 @@ self: super: with self; { cfn-lint = callPackage ../development/python-modules/cfn-lint { }; + cflib = callPackage ../development/python-modules/cflib { }; + cfscrape = callPackage ../development/python-modules/cfscrape { }; cftime = callPackage ../development/python-modules/cftime { }; @@ -7178,6 +7184,10 @@ self: super: with self; { libtorrent-rasterbar = (toPythonModule (pkgs.libtorrent-rasterbar.override { python3 = python; })).python; + libusb-package = callPackage ../development/python-modules/libusb-package { + inherit (pkgs) libusb1; + }; + libusb1 = callPackage ../development/python-modules/libusb1 { inherit (pkgs) libusb1; }; @@ -13276,6 +13286,8 @@ self: super: with self; { }; qtile-extras = callPackage ../development/python-modules/qtile-extras { }; + qtm = callPackage ../development/python-modules/qtm { }; + qtpy = callPackage ../development/python-modules/qtpy { }; quadprog = callPackage ../development/python-modules/quadprog { };