Skip to content

Commit 32abadf

Browse files
3.2 (#47)
1 parent e6eb5e9 commit 32abadf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+444
-318
lines changed

.github/workflows/run_tox.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
- uses: actions/setup-python@v5
1212
with:
1313
python-version: '3.10'
14-
- uses: pre-commit/action@v3.0.0
14+
- uses: pre-commit/action@v3.0.1
1515

1616

1717
tests:

.pre-commit-config.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.6.0
3+
rev: v5.0.0
44
hooks:
55
- id: check-ast
66
- id: check-builtin-literals
@@ -14,23 +14,35 @@ repos:
1414

1515

1616
- repo: https://github.com/astral-sh/ruff-pre-commit
17-
rev: v0.5.5
17+
rev: v0.7.2
1818
hooks:
19+
- id: ruff
20+
name: ruff unused imports
21+
# F401 [*] {name} imported but unused
22+
args: [ "--select", "F401", "--extend-exclude", "__init__.py", "--fix"]
23+
1924
- id: ruff
2025
# I001 [*] Import block is un-sorted or un-formatted
2126
# UP035 [*] Import from {target} instead: {names}
2227
# Q000 [*] Double quote found but single quotes preferred
2328
# Q001 [*] Double quote multiline found but single quotes preferred
2429
args: [ "--select", "I001,UP035,Q000,Q001", "--fix"]
2530

26-
- id: ruff
2731

2832
- repo: https://github.com/pre-commit/pygrep-hooks
2933
rev: v1.10.0
3034
hooks:
3135
- id: rst-backticks
3236

3337

38+
- repo: https://github.com/JelleZijlstra/autotyping
39+
rev: 24.9.0
40+
hooks:
41+
- id: autotyping
42+
types: [python]
43+
args: [--safe]
44+
45+
3446
- repo: meta
3547
hooks:
3648
- id: check-hooks-apply

.ruff.toml

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,103 @@
1-
2-
line-length = 120
31
indent-width = 4
2+
line-length = 120
43

54
target-version = "py310"
6-
src = ["src", "test"]
7-
8-
[lint]
95

10-
select = [
11-
"E", "W", # https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
12-
"I", # https://docs.astral.sh/ruff/rules/#isort-i
13-
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up
14-
15-
"A", # https://docs.astral.sh/ruff/rules/#flake8-builtins-a
16-
"ASYNC", # https://docs.astral.sh/ruff/rules/#flake8-async-async
17-
"C4", # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
18-
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
19-
"FIX", # https://docs.astral.sh/ruff/rules/#flake8-fixme-fix
20-
"INP", # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp
21-
"ISC", # https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc
22-
"PIE", # https://docs.astral.sh/ruff/rules/#flake8-pie-pie
23-
"PT", # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
24-
"PTH", # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
25-
"RET", # https://docs.astral.sh/ruff/rules/#flake8-return-ret
26-
"SIM", # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
27-
"SLOT", # https://docs.astral.sh/ruff/rules/#flake8-slots-slot
28-
"T10", # https://docs.astral.sh/ruff/rules/#flake8-debugger-t10
29-
"TCH", # https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch
30-
"TD", # https://docs.astral.sh/ruff/rules/#flake8-todos-td
31-
32-
"TRY", # https://docs.astral.sh/ruff/rules/#tryceratops-try
33-
"FLY", # https://docs.astral.sh/ruff/rules/#flynt-fly
34-
"PERF", # https://docs.astral.sh/ruff/rules/#perflint-perf
35-
"RUF", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
36-
37-
# "PL", # https://docs.astral.sh/ruff/rules/#pylint-pl
38-
# "FURB", # https://docs.astral.sh/ruff/rules/#refurb-furb
6+
src = [
7+
"src",
8+
"tests"
399
]
4010

11+
12+
[lint]
13+
select = ["ALL"]
14+
4115
ignore = [
16+
"D", # https://docs.astral.sh/ruff/rules/#pydocstyle-d
17+
"T20", # https://docs.astral.sh/ruff/rules/#flake8-print-t20
18+
"DTZ", # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
19+
"SLF", # https://docs.astral.sh/ruff/rules/#flake8-self-slf
20+
4221
"RET501", # https://docs.astral.sh/ruff/rules/unnecessary-return-none/#unnecessary-return-none-ret501
4322
"TRY400", # https://docs.astral.sh/ruff/rules/error-instead-of-exception/
4423

45-
"A003", # https://docs.astral.sh/ruff/rules/builtin-attribute-shadowing/
24+
# https://docs.astral.sh/ruff/rules/#flake8-builtins-a
25+
"A003", # Python builtin is shadowed by class attribute {name} from {row}
26+
27+
# https://docs.astral.sh/ruff/rules/#pyflakes-f
28+
"F401", # {name} imported but unused; consider using importlib.util.find_spec to test for availability
29+
30+
# https://docs.astral.sh/ruff/rules/#flake8-bandit-s
31+
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
32+
33+
# https://docs.astral.sh/ruff/rules/#pyupgrade-up
34+
"UP038", # Use X | Y in {} call instead of (X, Y)
35+
36+
# https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
37+
"ANN101", # Missing type annotation for {name} in method
38+
"ANN102", # Missing type annotation for {name} in classmethod
39+
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed in {name}
40+
41+
# https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble
42+
"BLE001", # Do not catch blind exception: {name}
43+
44+
# https://docs.astral.sh/ruff/rules/#flake8-raise-rse
45+
"RSE102", # Unnecessary parentheses on raised exception
46+
47+
# https://docs.astral.sh/ruff/rules/#flake8-commas-com
48+
"COM812", # Trailing comma missing
49+
"COM819", # Trailing comma prohibited
4650

47-
"UP038", # https://docs.astral.sh/ruff/rules/non-pep604-isinstance/
51+
# https://docs.astral.sh/ruff/rules/#warning-w_1
52+
"PLW0603", # Using the global statement to update {name} is discouraged
53+
54+
# https://docs.astral.sh/ruff/rules/#flake8-logging-format-g
55+
"G004", # Logging statement uses f-string
56+
57+
# https://docs.astral.sh/ruff/rules/#refactor-r
58+
"PLR1711", # Useless return statement at end of function
59+
60+
# https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
61+
"RUF005", # Consider {expression} instead of concatenation
4862
]
4963

5064

5165
[format]
52-
# Use single quotes for non-triple-quoted strings.
5366
quote-style = "single"
5467

5568

5669
# https://docs.astral.sh/ruff/settings/#lintflake8-quotes
5770
[lint.flake8-quotes]
58-
inline-quotes = "single"
71+
inline-quotes = "single"
5972
multiline-quotes = "single"
6073

6174

6275
[lint.flake8-builtins]
6376
builtins-ignorelist = ["id", "input"]
6477

6578

79+
# https://docs.astral.sh/ruff/settings/#lintisort
80+
[lint.isort]
81+
lines-after-imports = 2 # https://docs.astral.sh/ruff/settings/#lint_isort_lines-after-imports
82+
83+
6684
[lint.per-file-ignores]
67-
"docs/conf.py" = ["INP001", "A001"]
68-
"setup.py" = ["PTH123"]
69-
"tests/*" = [
70-
"ISC002", # Implicitly concatenated string literals over multiple lines
71-
"E501", # Line too long
72-
"INP001", # File `FILE_NAME` is part of an implicit namespace package. Add an `__init__.py`
85+
"docs/conf.py" = [
86+
"INP001", # File `conf.py` is part of an implicit namespace package. Add an `__init__.py`.
87+
"A001", # Variable `copyright` is shadowing a Python builtin
88+
"PTH118", # `os.path.join()` should be replaced by `Path` with `/` operator
89+
"PTH100", # `os.path.abspath()` should be replaced by `Path.resolve()`
7390
]
7491

92+
"setup.py" = ["PTH123"]
93+
94+
"tests/*" = [
95+
"ANN", # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
7596

97+
# https://docs.astral.sh/ruff/rules/#flake8-bandit-s
98+
"S101", # Use of assert detected
7699

77-
[lint.isort]
78-
# https://docs.astral.sh/ruff/settings/#lint_isort_lines-after-imports
79-
lines-after-imports = 2
100+
# https://docs.astral.sh/ruff/rules/#refactor-r
101+
"PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
102+
"PLR0913", # Too many arguments in function definition ({c_args} > {max_args})
103+
]

readme.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ To read from the serial port an IR to USB reader for energy meter is required.
2121

2222
# Changelog
2323

24+
#### 3.2 (2024-11-05)
25+
- Automatically select CRC e.g. for Holley DTZ541
26+
2427
#### 3.1 (2024-08-05)
2528
- Updated dependencies
2629
- Added some small log messages

requirements.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
-r requirements_setup.txt
22

33
# Testing
4-
pytest == 8.3.2
5-
pre-commit == 3.8.0
6-
pytest-asyncio == 0.23.8
4+
pytest == 8.3.3
5+
pre-commit == 4.0.1
6+
pytest-asyncio == 0.24.0
77
aioresponses == 0.7.6
88

99
# Linter
10-
ruff == 0.5.6
10+
ruff == 0.7.2

requirements_setup.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
aiomqtt == 2.2.0
1+
aiomqtt == 2.3.0
22
pyserial-asyncio == 0.6
33
easyconfig == 0.3.2
44
pydantic == 2.8.2
5-
smllib == 1.4
6-
aiohttp == 3.10.1
5+
smllib == 1.5
6+
aiohttp == 3.10.10

src/sml2mqtt/__log__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def get_logger(suffix: str) -> logging.Logger:
1818

1919
class MidnightRotatingFileHandler(RotatingFileHandler):
2020

21-
def __init__(self, *args, **kwargs):
21+
def __init__(self, *args, **kwargs) -> None:
2222
super().__init__(*args, **kwargs)
2323
self.last_check: date = datetime.now().date()
2424

@@ -29,7 +29,7 @@ def shouldRollover(self, record) -> int:
2929
return super().shouldRollover(record)
3030

3131

32-
def setup_log():
32+
def setup_log() -> None:
3333
level = sml2mqtt.CONFIG.logging.set_log_level()
3434

3535
# This is the longest logger name str

src/sml2mqtt/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from sml2mqtt.sml_source import create_source
1414

1515

16-
async def a_main():
16+
async def a_main() -> None:
1717
# Add possibility to stop program with Ctrl + c
1818
signal_handler_setup()
1919

src/sml2mqtt/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.1'
1+
__version__ = '3.2'

src/sml2mqtt/config/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,18 @@ class GeneralSettings(BaseModel):
3131
description='Additional OBIS fields for the serial number to configuration matching',
3232
alias='device id obis', in_file=False
3333
)
34+
crc: list[str] = Field(
35+
default=['x25', 'kermit'],
36+
description='Which crc algorithms are used to calculate the checksum of the smart meter',
37+
alias='crc', in_file=False
38+
)
3439

3540

3641
class Settings(AppBaseModel):
3742
logging: LoggingSettings = Field(default_factory=LoggingSettings)
3843
mqtt: MqttConfig = Field(default_factory=MqttConfig)
3944
general: GeneralSettings = Field(default_factory=GeneralSettings)
40-
inputs: list[HttpSourceSettings | SerialSourceSettings] = Field([], discriminator='type')
45+
inputs: list[HttpSourceSettings | SerialSourceSettings] = Field(default_factory=list, discriminator='type')
4146
devices: dict[LowerStr, SmlDeviceConfig] = Field({}, description='Device configuration by ID or url',)
4247

4348

src/sml2mqtt/config/logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
from easyconfig import BaseModel
4-
from pydantic import Extra, Field, field_validator
4+
from pydantic import Field, field_validator
55

66

77
class LoggingSettings(BaseModel):

src/sml2mqtt/config/operations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from sml2mqtt.const import DateTimeFinder, DurationType, TimeSeries
1313

14-
from .types import Number, ObisHex, PercentStr # noqa: TCH001
14+
from .types import Number, ObisHex # noqa: TCH001
1515

1616

1717
class EmptyKwargs(TypedDict):

src/sml2mqtt/const/protocols.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ class DeviceProto(Protocol):
88
def name(self) -> str:
99
...
1010

11-
def on_source_data(self, data: bytes):
11+
def on_source_data(self, data: bytes) -> None:
1212
...
1313

14-
def on_source_failed(self, reason: str):
14+
def on_source_failed(self, reason: str) -> None:
1515
...
1616

17-
def on_error(self, e: Exception, *, show_traceback: bool = True):
17+
def on_error(self, e: Exception, *, show_traceback: bool = True) -> None:
1818
...
1919

2020

2121
class SourceProto(Protocol):
22-
def start(self):
22+
def start(self) -> None:
2323
...
2424

25-
def cancel_and_wait(self):
25+
def cancel_and_wait(self) -> None:
2626
...

src/sml2mqtt/const/sml_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ def create(cls, timestamp: float, values: Iterable[SmlListEntry]):
5757
c.values[value.obis] = value
5858
return c
5959

60-
def __init__(self, timestamp: float):
60+
def __init__(self, timestamp: float) -> None:
6161
self.timestamp: Final = timestamp
6262
self.values: Final[dict[str, SmlListEntry]] = {}
6363

6464
def __getattr__(self, item: str) -> SmlListEntry:
6565
return self.values[item]
6666

67-
def __len__(self):
67+
def __len__(self) -> int:
6868
return len(self.values)
6969

7070
def get_value(self, obis: str) -> SmlListEntry | None:

0 commit comments

Comments
 (0)