Skip to content

Commit

Permalink
3.2 (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacemanspiff2007 authored Nov 5, 2024
1 parent e6eb5e9 commit 32abadf
Show file tree
Hide file tree
Showing 68 changed files with 444 additions and 318 deletions.
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

0 comments on commit 32abadf

Please sign in to comment.