Compare commits

...

18 Commits

Author SHA1 Message Date
geos_one
c7290907ed make compat to buster 2025-08-10 01:49:15 +02:00
root
d75e6c51bd Bump 2025-08-06 15:14:17 +02:00
root
206067cb4f Update upstream source from tag 'upstream/3.1.1'
Update to upstream version '3.1.1'
with Debian dir abc6ff77b6e18a0ca0d156a3c926935092e08854
2025-08-06 15:00:39 +02:00
root
e7961a02b2 New upstream version 3.1.1 2025-08-06 15:00:39 +02:00
Mario Fetka
c813f3cb15 update compat 2023-07-01 11:58:21 +02:00
Mario Fetka
3f4ba32dbb Imported Upstream version 3.1.0 2023-07-01 11:55:30 +02:00
Mario Fetka
502885fd23 update compat 2023-07-01 11:55:09 +02:00
Mario Fetka
8a6603ece7 Imported Upstream version 3.1.0 2023-07-01 11:54:39 +02:00
Mario Fetka
6efd4c00f8 Bump 2021-10-27 08:44:51 +02:00
Mario Fetka
9f2d889ce3 Imported Upstream version 3.0.0 2021-10-27 08:42:58 +02:00
Mario Fetka
7401b914a4 Imported Upstream version 3.0.0 2021-10-27 08:42:14 +02:00
Mario Fetka
38ddc53c2c build for stretch and jessie 2021-10-26 16:18:10 +02:00
Mario Fetka
16495c72e8 build for stretch and jessie 2021-10-26 16:07:46 +02:00
Mario Fetka
eb632a902b build for stretch and jessie 2021-10-26 16:04:21 +02:00
Mario Fetka
70834e1808 build for stretch and jessie 2021-10-26 15:02:23 +02:00
Mario Fetka
fdfbc23d0f build for stretch and jessie 2021-10-26 14:14:08 +02:00
Mario Fetka
1d2c07ae63 Imported Upstream version 2.2.1 2021-10-26 14:11:39 +02:00
Mario Fetka
3684dca243 correct deeps for bullseye 2021-10-26 13:17:45 +02:00
22 changed files with 187 additions and 111 deletions

57
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: CI
on:
pull_request: {}
push: {}
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install tox tox-gh-actions
- run: tox -e lint
check-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install tox tox-gh-actions
- run: tox -e check-docs
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
experimental: [false]
include:
- python-version: "3.12-dev"
experimental: true
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip setuptools
python3 -m pip install tox tox-gh-actions
- run: tox

View File

@ -1,37 +0,0 @@
language: python
dist: xenial
python:
- "3.6"
- "3.7"
- "3.8"
# TODO add 3.9
- "3.9-dev"
install: pip install tox-travis tox tox-venv
# Used by the `test` stage.
script: tox
stages:
- test
- lint
jobs:
allow_failures:
- python: "3.9-dev"
include:
# The `test` stage using the `python` matrix defined above
# is included implicitly.
- stage: lint
name: "Code Linting"
python: "3.7"
script: TOXENV=lint tox
- stage: check-docs
name: "Docs check"
python: "3.7"
script: TOXENV=check-docs tox

View File

@ -9,7 +9,7 @@ lint:
.PHONY: test
test:
coverage run -m py.test
coverage run -m pytest
coverage report
.PHONY: clean
@ -49,15 +49,11 @@ check-docs:
deb-local: clean sdist
docker build -t afancontrol-debuild -f ./Dockerfile.debian .
docker run -it --rm \
-e DEBFULLNAME="`git config --global user.name`" \
-e DEBEMAIL="`git config --global user.email`" \
-v `pwd`/dist:/afancontrol/dist \
-v `pwd`/debian:/afancontrol/debian \
afancontrol-debuild sh -ex -c '\
tar xaf /afancontrol/dist/afancontrol-*.tar.gz --strip 1; \
dch -v `python3 setup.py --version` -b --distribution=unstable; \
debuild -us -uc -b; \
cp debian/changelog /afancontrol/debian/; \
cd ../; \
ls -alh; \
mkdir /afancontrol/dist/debian; \

View File

@ -5,8 +5,8 @@ afancontrol
:target: https://pypi.python.org/pypi/afancontrol/
:alt: Latest Version
.. image:: https://img.shields.io/travis/KostyaEsmukov/afancontrol.svg?style=flat-square
:target: https://travis-ci.org/KostyaEsmukov/afancontrol
.. image:: https://img.shields.io/github/workflow/status/KostyaEsmukov/afancontrol/CI?style=flat-square
:target: https://github.com/KostyaEsmukov/afancontrol/actions
:alt: Build Status
.. image:: https://img.shields.io/github/license/KostyaEsmukov/afancontrol.svg?style=flat-square

10
debian/afancontrol.postinst.debhelper vendored Normal file
View File

@ -0,0 +1,10 @@
# Automatically added by dh_python3
if command -v py3compile >/dev/null 2>&1; then
py3compile -p afancontrol
fi
if command -v pypy3compile >/dev/null 2>&1; then
pypy3compile -p afancontrol || true
fi
# End automatically added section

12
debian/afancontrol.postrm.debhelper vendored Normal file
View File

@ -0,0 +1,12 @@
# Automatically added by dh_installsystemd/13.24.2
if [ "$1" = remove ] && [ -d /run/systemd/system ] ; then
systemctl --system daemon-reload >/dev/null || true
fi
# End automatically added section
# Automatically added by dh_installsystemd/13.24.2
if [ "$1" = "purge" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper purge 'afancontrol.service' >/dev/null || true
fi
fi
# End automatically added section

10
debian/afancontrol.prerm.debhelper vendored Normal file
View File

@ -0,0 +1,10 @@
# Automatically added by dh_python3
if command -v py3clean >/dev/null 2>&1; then
py3clean -p afancontrol
else
dpkg -L afancontrol | sed -En -e '/^(.*)\/(.+)\.py$/s,,rm "\1/__pycache__/\2".*,e'
find /usr/lib/python3/dist-packages/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir
fi
# End automatically added section

3
debian/afancontrol.substvars vendored Normal file
View File

@ -0,0 +1,3 @@
python3:Depends=python3-click, python3:any
misc:Depends=
misc:Pre-Depends=

26
debian/changelog vendored
View File

@ -1,3 +1,29 @@
afancontrol (3.1.1-1) UNRELEASED; urgency=medium
[ Mario Fetka ]
* Imported Upstream version 3.1.0
[ root ]
* New upstream version 3.1.1
-- root <mario.fetka@disconnected-by-peer.at> Wed, 06 Aug 2025 15:01:06 +0200
afancontrol (3.1.0-1) unstable; urgency=medium
[ Juha Yrjölä ]
* Support glob expansion with fans (#9)
[ Kostya Esmukov ]
* Drop Python 3.6 support, add 3.11
-- Kostya Esmukov <kostya@esmukov.ru> Mon, 28 Nov 2022 00:11:43 +0200
afancontrol (3.0.0-2) unstable; urgency=medium
* Bump debhelper compat to 13
-- Kostya Esmukov <kostya@esmukov.ru> Mon, 02 Aug 2021 19:19:34 +0000
afancontrol (3.0.0-1) unstable; urgency=medium
* Drop support for prometheus-client < 0.1.0 (debian stretch)

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

30
debian/control vendored
View File

@ -2,37 +2,29 @@ Source: afancontrol
Section: utils
Priority: optional
Maintainer: Kostya Esmukov <kostya@esmukov.ru>
Build-Depends: debhelper (>= 9),
Build-Depends: debhelper-compat (= 12),
dh-python,
dh-systemd,
python3-all,
python3-click,
python3-prometheus-client (>= 0.1.0),
python3-pytest,
python3-requests,
python3-serial,
python3-setuptools
Build-Depends-Indep: python3-pytest,
python3-requests,
python3-click,
python3-prometheus-client (>= 0.1.0),
python3-serial
Standards-Version: 3.9.8
Homepage: https://github.com/KostyaEsmukov/afancontrol
X-Python3-Version: >= 3.5
#Vcs-Git: https://anonscm.debian.org/git/python-modules/packages/python3-afancontrol.git
#Vcs-Browser: https://anonscm.debian.org/cgit/python-modules/packages/python3-afancontrol.git/
#Testsuite: autopkgtest-pkg-python
Package: afancontrol
Architecture: all
Depends: ${python3:Depends},
${misc:Depends},
hddtemp,
Depends: hddtemp,
lm-sensors,
python3-click,
python3-pkg-resources,
python3-prometheus-client (>= 0.1.0),
python3-serial
Suggests: freeipmi-tools,
python3-serial,
${misc:Depends},
${python3:Depends}
Suggests: freeipmi-tools
Description: Advanced Fan Control program (Python 3)
afancontrol is an Advanced Fan Control program, which controls PWM
fans according to the current temperatures of the system components.
.
This package installs the library for Python 3.

2
debian/rules vendored Normal file → Executable file
View File

@ -9,4 +9,4 @@ export PYBUILD_TEST_PYTEST=1
export PYBUILD_TEST_ARGS={dir}/tests/
%:
dh $@ --with systemd,python3 --buildsystem=pybuild
dh $@ --with python3 --buildsystem=pybuild

View File

@ -25,13 +25,8 @@ per-file-ignores =
src/afancontrol/config.py:C901
[isort]
; https://github.com/timothycrosley/isort#multi-line-output-modes
multi_line_output = 3
; https://github.com/ambv/black#how-black-wraps-lines
include_trailing_comma = True
force_grid_wrap = 0
combine_as_imports = True
line_length = 88
profile = black
[metadata]
author = Kostya Esmukov
@ -45,10 +40,6 @@ classifier =
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Topic :: System :: Hardware
Topic :: System :: Monitoring
Topic :: System :: Systems Administration
@ -76,7 +67,7 @@ install_requires =
package_dir =
= src
packages = find:
python_requires = >=3.6
python_requires = >=3.7
[options.entry_points]
console_scripts =
@ -88,15 +79,16 @@ arduino =
metrics =
prometheus-client>=0.1.0
dev =
black==20.8b1
coverage==5.3
flake8==3.8.4
isort==5.5.4
mypy==0.782
pytest==6.1.0
black==22.10.0
coverage==6.5.0
flake8==5.0.4
isort==5.10.1
mypy==0.990
pytest==7.2.0
sphinx==4.3.2
vcrpy==4.2.1
requests
sphinx==3.2.1
wheel
types-requests
[options.packages.find]
where = src

View File

@ -1 +1 @@
__version__ = "3.0.0"
__version__ = "3.1.0"

View File

@ -1,4 +1,5 @@
import configparser
import glob
from typing import Any, Generic, Iterator, Optional, Type, TypeVar, Union, overload
T = TypeVar("T", bound=str)
@ -127,3 +128,12 @@ class ConfigParserSection(Generic[T]):
"[%s] %r option is expected to be set" % (self.__section.name, option)
)
return res
def expand_glob(path: str):
matches = glob.glob(path)
if not matches:
return path # a FileNotFoundError will be raised on a first read attempt
if len(matches) == 1:
return matches[0]
raise ValueError("Expected glob to expand to a single path, got %r" % (matches,))

View File

@ -187,7 +187,8 @@ def fantest(
elif fan_type == "arduino":
if not arduino_serial_url:
arduino_serial_url = click.prompt(
"\n%s\nArduino Serial url" % HELP_ARDUINO_SERIAL_URL, type=str
"\n%s\nArduino Serial url" % HELP_ARDUINO_SERIAL_URL,
type=str, # type: ignore
)
# typeshed currently specifies `Optional[str]` for `default`,
@ -197,17 +198,19 @@ def fantest(
# Hence the `type: ignore`.
arduino_baudrate = click.prompt( # type: ignore
"\n%s\nBaudrate" % HELP_ARDUINO_BAUDRATE,
type=int,
type=int, # type: ignore
default=str(arduino_baudrate),
show_default=True,
)
if not arduino_pwm_pin and arduino_pwm_pin != 0:
arduino_pwm_pin = click.prompt(
"\n%s\nArduino PWM pin" % HELP_ARDUINO_PWM_PIN, type=int
"\n%s\nArduino PWM pin" % HELP_ARDUINO_PWM_PIN,
type=int, # type: ignore
)
if not arduino_tacho_pin and arduino_tacho_pin != 0:
arduino_tacho_pin = click.prompt(
"\n%s\nArduino Tachometer pin" % HELP_ARDUINO_TACHO_PIN, type=int
"\n%s\nArduino Tachometer pin" % HELP_ARDUINO_TACHO_PIN,
type=int, # type: ignore
)
assert arduino_serial_url is not None

View File

@ -1,11 +1,13 @@
import abc
from typing import NewType, Type
from typing import NewType, Tuple, Type
PWMValue = NewType("PWMValue", int) # [0..255]
FanValue = NewType("FanValue", int)
class _SlotsReprMixin:
__slots__: Tuple[str, ...]
def __eq__(self, other):
if isinstance(other, type(self)):
for attr in self.__slots__:

View File

@ -1,7 +1,7 @@
from pathlib import Path
from typing import NewType
from afancontrol.configparser import ConfigParserSection
from afancontrol.configparser import ConfigParserSection, expand_glob
from afancontrol.pwmfan.base import (
BaseFanPWMRead,
BaseFanPWMWrite,
@ -18,7 +18,7 @@ class LinuxFanSpeed(BaseFanSpeed):
__slots__ = ("_fan_input",)
def __init__(self, fan_input: FanInputDevice) -> None:
self._fan_input = Path(fan_input)
self._fan_input = Path(expand_glob(fan_input))
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanSpeed:
@ -35,7 +35,7 @@ class LinuxFanPWMRead(BaseFanPWMRead):
min_pwm = PWMValue(0)
def __init__(self, pwm: PWMDevice) -> None:
self._pwm = Path(pwm)
self._pwm = Path(expand_glob(pwm))
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMRead:
@ -51,8 +51,9 @@ class LinuxFanPWMWrite(BaseFanPWMWrite):
read_cls = LinuxFanPWMRead
def __init__(self, pwm: PWMDevice) -> None:
self._pwm = Path(pwm)
self._pwm_enable = Path(pwm + "_enable")
base = expand_glob(pwm)
self._pwm = Path(base)
self._pwm_enable = Path(base + "_enable")
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMWrite:

View File

@ -1,21 +1,11 @@
import glob
import re
from pathlib import Path
from typing import Optional, Tuple
from afancontrol.configparser import ConfigParserSection
from afancontrol.configparser import ConfigParserSection, expand_glob
from afancontrol.temp.base import Temp, TempCelsius
def _expand_glob(path: str):
matches = glob.glob(path)
if not matches:
return path # a FileNotFoundError will be raised on a first read attempt
if len(matches) == 1:
return matches[0]
raise ValueError("Expected glob to expand to a single path, got %r" % (matches,))
class FileTemp(Temp):
def __init__(
self,
@ -33,7 +23,7 @@ class FileTemp(Temp):
# /sys/devices/pci0000:00/0000:00:01.3/[...]/hwmon/hwmon*/temp1_input
# The `hwmon*` might change after reboot, but it is always a single
# directory within the device.
temp_path = _expand_glob(temp_path + "_input")
temp_path = expand_glob(temp_path + "_input")
temp_path = re.sub(r"_input$", "", temp_path)
self._temp_input = Path(temp_path + "_input")

View File

@ -6,7 +6,8 @@ import pytest
from click.testing import CliRunner
from afancontrol import daemon
from afancontrol.daemon import PidFile, Signals, daemon as main
from afancontrol.daemon import PidFile, Signals
from afancontrol.daemon import daemon as main
def test_main_smoke(temp_path):

View File

@ -10,9 +10,9 @@ from afancontrol.fantest import (
CSVMeasurementsOutput,
HumanMeasurementsOutput,
MeasurementsOutput,
fantest as main,
run_fantest,
)
from afancontrol.fantest import fantest as main
from afancontrol.fantest import run_fantest
from afancontrol.pwmfan import (
BaseFanPWMRead,
BaseFanPWMWrite,

11
tox.ini
View File

@ -1,5 +1,5 @@
[tox]
envlist=py{36,37,38,39,310}{,-arduino,-metrics},lint,check-docs
envlist=py{37,38,39,310,311,312}{,-arduino,-metrics},lint,check-docs
[testenv]
extras =
@ -12,6 +12,15 @@ commands = make test
; sources to the working dir by default.
usedevelop = True
[gh-actions]
python =
3.7: py37
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
[testenv:lint]
extras =
arduino