Skip to content
Merged
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
6 changes: 5 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ repos:
# types: [python]
# require_serial: true
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.18.2
rev: v1.20.1
hooks:
- id: mypy
exclude: cli.py
additional_dependencies:
- "pydantic>=2.0.0"
- "pytest>=8.0.0"
- "types-xmltodict >=1.0.1,<2.0.0"
- "click >=8.0.0,<9.0.0"
- "scapy>=2.6.1,<3.0.0"
args: [ "--config-file=./pyproject.toml"]
files: ^pyomnilogic_local/.+\.(py|pyi)$
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.14.2
10 changes: 8 additions & 2 deletions pyomnilogic_local/api/mock_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
import json
import logging
from pathlib import Path
from typing import Any, Literal, overload
from typing import Any, Literal, TypedDict, overload

from pyomnilogic_local.models.mspconfig import MSPConfig
from pyomnilogic_local.models.telemetry import Telemetry

_LOGGER = logging.getLogger(__name__)


class SimData(TypedDict):
telemetry: str
msp_config: str
filepath: str


class OmniLogicMockAPI:
"""Drop-in replacement for OmniLogicAPI that serves pre-recorded data from one or more JSON files.

Expand Down Expand Up @@ -43,7 +49,7 @@ def __init__(self, filepath: str) -> None:
"""
paths = filepath.split(",")

self._sim_data: list[dict[str, Any]] = []
self._sim_data: list[SimData] = []
for fp in paths:
path = Path(fp)
if not path.exists():
Expand Down
14 changes: 12 additions & 2 deletions pyomnilogic_local/models/filter_diagnostics.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, ValidationError
from xmltodict import parse as xml_parse

from pyomnilogic_local.models.exceptions import OmniParsingError

# Example Filter Diagnostics XML:
#
# <?xml version="1.0" encoding="UTF-8" ?>
Expand Down Expand Up @@ -46,6 +48,7 @@ class FilterDiagnosticsParameters(BaseModel):

class FilterDiagnostics(BaseModel):
model_config = ConfigDict(from_attributes=True)
_raw: str = PrivateAttr(default="")

name: str = Field(alias="Name")
parameters: list[FilterDiagnosticsParameter] = Field(alias="Parameters")
Expand All @@ -64,4 +67,11 @@ def load_xml(xml: str) -> FilterDiagnostics:
# The XML nests the Parameter entries under a Parameters entry, this is annoying to work with. Here we are adjusting the data to
# remove that extra level in the data
data["Response"]["Parameters"] = data["Response"]["Parameters"]["Parameter"]
return FilterDiagnostics.model_validate(data["Response"])
try:
instance = FilterDiagnostics.model_validate(data["Response"])
instance._raw = xml
except ValidationError as exc:
msg = f"Failed to parse Filter Diagnostics: {exc}"
raise OmniParsingError(msg) from exc
else:
return instance
2 changes: 1 addition & 1 deletion pyomnilogic_local/models/leadmessage.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def parse_xml_element(cls, data: Any) -> dict[str, Any]:
if name := param.get("name"):
result[name] = int(param.text) if param.text else 0
return result
return data
return data # type: ignore[no-any-return]
7 changes: 6 additions & 1 deletion pyomnilogic_local/models/mspconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
BaseModel,
ConfigDict,
Field,
PrivateAttr,
ValidationError,
computed_field,
model_validator,
Expand Down Expand Up @@ -410,6 +411,7 @@ def days_active(self) -> list[str]:

class MSPConfig(BaseModel):
model_config = ConfigDict(from_attributes=True)
_raw: str = PrivateAttr(default="")

system: MSPSystem = Field(alias="System")
backyard: MSPBackyard = Field(alias="Backyard")
Expand Down Expand Up @@ -459,7 +461,10 @@ def load_xml(xml: str) -> MSPConfig:
),
)
try:
return MSPConfig.model_validate(data["MSPConfig"], from_attributes=True)
instance = MSPConfig.model_validate(data["MSPConfig"], from_attributes=True)
instance._raw = xml
except ValidationError as exc:
msg = f"Failed to parse MSP Configuration: {exc}"
raise OmniParsingError(msg) from exc
else:
return instance
10 changes: 7 additions & 3 deletions pyomnilogic_local/models/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from typing import Any, SupportsInt, cast, overload

from pydantic import BaseModel, ConfigDict, Field, ValidationError, computed_field
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, ValidationError, computed_field
from xmltodict import parse as xml_parse

from pyomnilogic_local.omnitypes import (
Expand Down Expand Up @@ -492,6 +492,7 @@ class Telemetry(BaseModel):
"""

model_config = ConfigDict(from_attributes=True)
_raw: str = PrivateAttr(default="")

version: str = Field(alias="@version")
backyard: TelemetryBackyard = Field(alias="Backyard")
Expand Down Expand Up @@ -525,7 +526,7 @@ def xml_postprocessor(path: Any, key: Any, value: SupportsInt | Any) -> tuple[An

try:
newvalue = int(value)
except (ValueError, TypeError):
except ValueError, TypeError:
newvalue = value

return key, newvalue
Expand All @@ -552,10 +553,13 @@ def xml_postprocessor(path: Any, key: Any, value: SupportsInt | Any) -> tuple[An
),
)
try:
return Telemetry.model_validate(data["STATUS"])
instance = Telemetry.model_validate(data["STATUS"])
instance._raw = xml
except ValidationError as exc:
msg = f"Failed to parse Telemetry: {exc}"
raise OmniParsingError(msg) from exc
else:
return instance

def get_telem_by_systemid(self, system_id: int) -> TelemetryType | None:
for field_name, value in self:
Expand Down
9 changes: 2 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,9 @@ dev = [

[tool.mypy]
python_version = "3.14"
plugins = [
"pydantic.mypy"
]
# follow_imports = "silent"
plugins = ["pydantic.mypy"]
follow_imports = "normal"
strict = true
ignore_missing_imports = true
disallow_subclassing_any = false
warn_return_any = false

[tool.ruff]
line-length = 140
Expand Down
Loading