Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.2 #47

Merged
merged 2 commits into from
Nov 5, 2024
Merged

3.2 #47

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run_tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: pre-commit/[email protected].0
- uses: pre-commit/[email protected].1


tests:
Expand Down
18 changes: 15 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-ast
- id: check-builtin-literals
Expand All @@ -14,23 +14,35 @@ repos:


- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.5
rev: v0.7.2
hooks:
- id: ruff
name: ruff unused imports
# F401 [*] {name} imported but unused
args: [ "--select", "F401", "--extend-exclude", "__init__.py", "--fix"]

- id: ruff
# I001 [*] Import block is un-sorted or un-formatted
# UP035 [*] Import from {target} instead: {names}
# Q000 [*] Double quote found but single quotes preferred
# Q001 [*] Double quote multiline found but single quotes preferred
args: [ "--select", "I001,UP035,Q000,Q001", "--fix"]

- id: ruff

- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: rst-backticks


- repo: https://github.com/JelleZijlstra/autotyping
rev: 24.9.0
hooks:
- id: autotyping
types: [python]
args: [--safe]


- repo: meta
hooks:
- id: check-hooks-apply
Expand Down
118 changes: 71 additions & 47 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -1,79 +1,103 @@

line-length = 120
indent-width = 4
line-length = 120

target-version = "py310"
src = ["src", "test"]

[lint]

select = [
"E", "W", # https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
"I", # https://docs.astral.sh/ruff/rules/#isort-i
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up

"A", # https://docs.astral.sh/ruff/rules/#flake8-builtins-a
"ASYNC", # https://docs.astral.sh/ruff/rules/#flake8-async-async
"C4", # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
"FIX", # https://docs.astral.sh/ruff/rules/#flake8-fixme-fix
"INP", # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp
"ISC", # https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc
"PIE", # https://docs.astral.sh/ruff/rules/#flake8-pie-pie
"PT", # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
"PTH", # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
"RET", # https://docs.astral.sh/ruff/rules/#flake8-return-ret
"SIM", # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
"SLOT", # https://docs.astral.sh/ruff/rules/#flake8-slots-slot
"T10", # https://docs.astral.sh/ruff/rules/#flake8-debugger-t10
"TCH", # https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch
"TD", # https://docs.astral.sh/ruff/rules/#flake8-todos-td

"TRY", # https://docs.astral.sh/ruff/rules/#tryceratops-try
"FLY", # https://docs.astral.sh/ruff/rules/#flynt-fly
"PERF", # https://docs.astral.sh/ruff/rules/#perflint-perf
"RUF", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf

# "PL", # https://docs.astral.sh/ruff/rules/#pylint-pl
# "FURB", # https://docs.astral.sh/ruff/rules/#refurb-furb
src = [
"src",
"tests"
]


[lint]
select = ["ALL"]

ignore = [
"D", # https://docs.astral.sh/ruff/rules/#pydocstyle-d
"T20", # https://docs.astral.sh/ruff/rules/#flake8-print-t20
"DTZ", # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
"SLF", # https://docs.astral.sh/ruff/rules/#flake8-self-slf

"RET501", # https://docs.astral.sh/ruff/rules/unnecessary-return-none/#unnecessary-return-none-ret501
"TRY400", # https://docs.astral.sh/ruff/rules/error-instead-of-exception/

"A003", # https://docs.astral.sh/ruff/rules/builtin-attribute-shadowing/
# https://docs.astral.sh/ruff/rules/#flake8-builtins-a
"A003", # Python builtin is shadowed by class attribute {name} from {row}

# https://docs.astral.sh/ruff/rules/#pyflakes-f
"F401", # {name} imported but unused; consider using importlib.util.find_spec to test for availability

# https://docs.astral.sh/ruff/rules/#flake8-bandit-s
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes

# https://docs.astral.sh/ruff/rules/#pyupgrade-up
"UP038", # Use X | Y in {} call instead of (X, Y)

# https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
"ANN101", # Missing type annotation for {name} in method
"ANN102", # Missing type annotation for {name} in classmethod
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed in {name}

# https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble
"BLE001", # Do not catch blind exception: {name}

# https://docs.astral.sh/ruff/rules/#flake8-raise-rse
"RSE102", # Unnecessary parentheses on raised exception

# https://docs.astral.sh/ruff/rules/#flake8-commas-com
"COM812", # Trailing comma missing
"COM819", # Trailing comma prohibited

"UP038", # https://docs.astral.sh/ruff/rules/non-pep604-isinstance/
# https://docs.astral.sh/ruff/rules/#warning-w_1
"PLW0603", # Using the global statement to update {name} is discouraged

# https://docs.astral.sh/ruff/rules/#flake8-logging-format-g
"G004", # Logging statement uses f-string

# https://docs.astral.sh/ruff/rules/#refactor-r
"PLR1711", # Useless return statement at end of function

# https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
"RUF005", # Consider {expression} instead of concatenation
]


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


# https://docs.astral.sh/ruff/settings/#lintflake8-quotes
[lint.flake8-quotes]
inline-quotes = "single"
inline-quotes = "single"
multiline-quotes = "single"


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


# https://docs.astral.sh/ruff/settings/#lintisort
[lint.isort]
lines-after-imports = 2 # https://docs.astral.sh/ruff/settings/#lint_isort_lines-after-imports


[lint.per-file-ignores]
"docs/conf.py" = ["INP001", "A001"]
"setup.py" = ["PTH123"]
"tests/*" = [
"ISC002", # Implicitly concatenated string literals over multiple lines
"E501", # Line too long
"INP001", # File `FILE_NAME` is part of an implicit namespace package. Add an `__init__.py`
"docs/conf.py" = [
"INP001", # File `conf.py` is part of an implicit namespace package. Add an `__init__.py`.
"A001", # Variable `copyright` is shadowing a Python builtin
"PTH118", # `os.path.join()` should be replaced by `Path` with `/` operator
"PTH100", # `os.path.abspath()` should be replaced by `Path.resolve()`
]

"setup.py" = ["PTH123"]

"tests/*" = [
"ANN", # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann

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

[lint.isort]
# https://docs.astral.sh/ruff/settings/#lint_isort_lines-after-imports
lines-after-imports = 2
# https://docs.astral.sh/ruff/rules/#refactor-r
"PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
"PLR0913", # Too many arguments in function definition ({c_args} > {max_args})
]
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ To read from the serial port an IR to USB reader for energy meter is required.

# Changelog

#### 3.2 (2024-11-05)
- Automatically select CRC e.g. for Holley DTZ541

#### 3.1 (2024-08-05)
- Updated dependencies
- Added some small log messages
Expand Down
8 changes: 4 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
-r requirements_setup.txt

# Testing
pytest == 8.3.2
pre-commit == 3.8.0
pytest-asyncio == 0.23.8
pytest == 8.3.3
pre-commit == 4.0.1
pytest-asyncio == 0.24.0
aioresponses == 0.7.6

# Linter
ruff == 0.5.6
ruff == 0.7.2
6 changes: 3 additions & 3 deletions requirements_setup.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
aiomqtt == 2.2.0
aiomqtt == 2.3.0
pyserial-asyncio == 0.6
easyconfig == 0.3.2
pydantic == 2.8.2
smllib == 1.4
aiohttp == 3.10.1
smllib == 1.5
aiohttp == 3.10.10
4 changes: 2 additions & 2 deletions src/sml2mqtt/__log__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def get_logger(suffix: str) -> logging.Logger:

class MidnightRotatingFileHandler(RotatingFileHandler):

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

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


def setup_log():
def setup_log() -> None:
level = sml2mqtt.CONFIG.logging.set_log_level()

# This is the longest logger name str
Expand Down
2 changes: 1 addition & 1 deletion src/sml2mqtt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from sml2mqtt.sml_source import create_source


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

Expand Down
2 changes: 1 addition & 1 deletion src/sml2mqtt/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.1'
__version__ = '3.2'
7 changes: 6 additions & 1 deletion src/sml2mqtt/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ class GeneralSettings(BaseModel):
description='Additional OBIS fields for the serial number to configuration matching',
alias='device id obis', in_file=False
)
crc: list[str] = Field(
default=['x25', 'kermit'],
description='Which crc algorithms are used to calculate the checksum of the smart meter',
alias='crc', in_file=False
)


class Settings(AppBaseModel):
logging: LoggingSettings = Field(default_factory=LoggingSettings)
mqtt: MqttConfig = Field(default_factory=MqttConfig)
general: GeneralSettings = Field(default_factory=GeneralSettings)
inputs: list[HttpSourceSettings | SerialSourceSettings] = Field([], discriminator='type')
inputs: list[HttpSourceSettings | SerialSourceSettings] = Field(default_factory=list, discriminator='type')
devices: dict[LowerStr, SmlDeviceConfig] = Field({}, description='Device configuration by ID or url',)


Expand Down
2 changes: 1 addition & 1 deletion src/sml2mqtt/config/logging.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

from easyconfig import BaseModel
from pydantic import Extra, Field, field_validator
from pydantic import Field, field_validator


class LoggingSettings(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion src/sml2mqtt/config/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from sml2mqtt.const import DateTimeFinder, DurationType, TimeSeries

from .types import Number, ObisHex, PercentStr # noqa: TCH001
from .types import Number, ObisHex # noqa: TCH001


class EmptyKwargs(TypedDict):
Expand Down
10 changes: 5 additions & 5 deletions src/sml2mqtt/const/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ class DeviceProto(Protocol):
def name(self) -> str:
...

def on_source_data(self, data: bytes):
def on_source_data(self, data: bytes) -> None:
...

def on_source_failed(self, reason: str):
def on_source_failed(self, reason: str) -> None:
...

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


class SourceProto(Protocol):
def start(self):
def start(self) -> None:
...

def cancel_and_wait(self):
def cancel_and_wait(self) -> None:
...
4 changes: 2 additions & 2 deletions src/sml2mqtt/const/sml_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ def create(cls, timestamp: float, values: Iterable[SmlListEntry]):
c.values[value.obis] = value
return c

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

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

def __len__(self):
def __len__(self) -> int:
return len(self.values)

def get_value(self, obis: str) -> SmlListEntry | None:
Expand Down
Loading