diff --git a/.SRCINFO b/.SRCINFO index dc13e8f..10892d2 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = amdfan pkgdesc = Python daemon for controlling the fans on amdgpu cards - pkgver = 0.1.5 + pkgver = 0.1.6 pkgrel = 1 url = https://github.com/mcgillij/amdfan arch = any @@ -11,7 +11,7 @@ pkgbase = amdfan depends = python-numpy depends = python-rich depends = python-click - source = https://github.com/mcgillij/amdfan/archive/0.1.5.tar.gz + source = https://github.com/mcgillij/amdfan/archive/0.1.6.tar.gz md5sums = SKIP pkgname = amdfan diff --git a/PKGBUILD b/PKGBUILD index 03e8f9a..d21c735 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -3,7 +3,7 @@ pkgname=amdfan pkgdesc="Python daemon for controlling the fans on amdgpu cards" -pkgver=0.1.5 +pkgver=0.1.6 pkgrel=1 arch=('any') license=('GPL2') diff --git a/README.md b/README.md index 33361fa..13eacd0 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,12 @@ These are all addressed in Amdfan, and as long as I’ve still got some AMD card Usage: amdfan.py [OPTIONS] Options: - --daemon Run as daemon applying the fan curve - --monitor Run as a monitor showing temp and fan speed - --manual Manually set the fan speed value of a card - --help Show this message and exit. + --daemon Run as daemon applying the fan curve + --monitor Run as a monitor showing temp and fan speed + --manual Manually set the fan speed value of a card + --configuration Prints out the default configuration for you to use + --service Prints out the amdfan.service file to use with systemd + --help Show this message and exit. ``` ## Daemon @@ -56,7 +58,18 @@ You can use Amdfan to monitor your AMD video cards using the ```--monitor``` fla ## Manual -Alternatively if you don't want to set a fan curve, you can just apply a fan setting manually. Also allows you to revert the fan control to the systems default behavior by using the "auto" parameter. +Alternatively if you don't want to set a fan curve, you can just apply a fan setting manually. +Also allows you to revert the fan control to the systems default behavior by using the "auto" parameter. +![screenshot](https://raw.githubusercontent.com/mcgillij/amdfan/main/images/manual.png) + +## Configuration + +This will dump out the default configuration that would get generated for `/etc/amdfan.yml` when you first run it as a service. This allows you to configure the settings prior to running it as a daemon if you wish. + +## Service + +This is just a convenience method for dumping out the `amdfan.service` that would get installed if you used a package manager to install amdfan. Useful if you installed the module via `pip`, `pipenv` or `poetry` vs using the package manager version. + ## Note @@ -92,6 +105,28 @@ speed_matrix: # - card0 ``` +## Running the systemd service + +To run the service, if you installed amdfan using the AUR package, you can run the following commands to **start/enable** the service. + +``` bash +sudo systemctl start amdfan +sudo systemctl enable amdfan +``` + +After you've started it, you may want to edit the settings found in `/etc/amdfan.yml`. Once your happy with those, you can restart amdfan with the following command. + +``` bash +sudo systemctl restart amdfan +``` + +## Checking the status +You can check the systemd service status with the following command: + +``` bash +systemctl status amdfan +``` + ## Building Python package Requires Poetry to be installed diff --git a/amdfan/amdfan.py b/amdfan/amdfan.py index 2dab9ca..059e892 100755 --- a/amdfan/amdfan.py +++ b/amdfan/amdfan.py @@ -29,6 +29,46 @@ HWMON_DIR = "device/hwmon" LOGGER = logging.getLogger("rich") +DEFAULT_FAN_CONFIG = """#Fan Control Matrix. +# [,] +speed_matrix: +- [4, 4] +- [30, 33] +- [45, 50] +- [60, 66] +- [65, 69] +- [70, 75] +- [75, 89] +- [80, 100] + +# Current Min supported value is 4 due to driver bug +# +# Optional configuration options +# +# Allows for some leeway +/- temp, as to not constantly change fan speed +# threshold: 4 +# +# Frequency will chance how often we probe for the temp +# frequency: 5 +# +# While frequency and threshold are optional, I highly recommend finding +# settings that work for you. I've included the defaults I use above. +# +# cards: +# can be any card returned from `ls /sys/class/drm | grep "^card[[:digit:]]$"` +# - card0 +""" + +SYSTEMD_SERVICE = """[Unit] +Description=amdfan controller + +[Service] +ExecStart=/usr/bin/amdfan --daemon +Restart=always + +[Install] +WantedBy=multi-user.target +""" logging.basicConfig( level=logging.DEBUG if DEBUG else logging.INFO, @@ -276,45 +316,34 @@ def load_config(path): default=False, help="Manually set the fan speed value of a card", ) -def cli(daemon, monitor, manual): +@click.option( + "--configuration", + is_flag=True, + default=False, + help="Prints out the default configuration for you to use" +) +@click.option( + "--service", + is_flag=True, + default=False, + help="Prints out the amdfan.service file to use with systemd" +) +def cli(daemon, monitor, manual, configuration, service): if daemon: run_as_daemon() elif monitor: monitor_cards() elif manual: set_fan_speed() + elif configuration: + print(DEFAULT_FAN_CONFIG) + elif service: + print(SYSTEMD_SERVICE) else: c.print("Try: --help to see the options") def run_as_daemon(): - - default_fan_config = """#Fan Control Matrix. -# [,] -speed_matrix: -- [4, 4] -- [30, 33] -- [45, 50] -- [60, 66] -- [65, 69] -- [70, 75] -- [75, 89] -- [80, 100] - -# Current Min supported value is 4 due to driver bug -# -# Optional configuration options -# -# Allows for some leeway +/- temp, as to not constantly change fan speed -# threshold: 2 -# -# Frequency will chance how often we probe for the temp -# frequency: 5 -# -# cards: -# can be any card returned from `ls /sys/class/drm | grep "^card[[:digit:]]$"` -# - card0 -""" config = None for location in CONFIG_LOCATIONS: if os.path.isfile(location): @@ -324,7 +353,7 @@ def run_as_daemon(): if config is None: LOGGER.info("No config found, creating one in %s", CONFIG_LOCATIONS[-1]) with open(CONFIG_LOCATIONS[-1], "w") as config_file: - config_file.write(default_fan_config) + config_file.write(DEFAULT_FAN_CONFIG) config_file.flush() config = load_config(CONFIG_LOCATIONS[-1]) diff --git a/images/manual.png b/images/manual.png new file mode 100644 index 0000000..c55852d Binary files /dev/null and b/images/manual.png differ diff --git a/pyproject.toml b/pyproject.toml index 1791826..6413b7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "amdfan" -version = "0.1.5" +version = "0.1.6" description = "Fan monitor and controller for AMD gpus in Linux" authors = ["mcgillij "] license = "GPL-2.0-only" diff --git a/tests/test_cli.py b/tests/test_cli.py index c6a0063..1dff60b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -14,6 +14,12 @@ def test_params(self): help_param = "--help" result = runner.invoke(cli, help_param) assert result.exit_code == 0 + config_param = "--configuration" + result = runner.invoke(cli, config_param) + assert result.exit_code == 0 + service_param = "--service" + result = runner.invoke(cli, service_param) + assert result.exit_code == 0 manual_param = "--manual" result = runner.invoke(cli, manual_param, input='\n'.join(['card0', "25"])) assert result.exception