Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
11c4eaf
Improve developer documentation (#1908)
iMicknl Jan 24, 2026
6d741a2
Fix uv.lock after rebase
iMicknl Jan 25, 2026
a112362
Add UnknownEnumMixin for consistent handling of unknown enum values
iMicknl Jan 27, 2026
6fc47ef
Refactor enums to use UnknownEnumMixin for consistent handling and im…
iMicknl Jan 27, 2026
11db351
Add methods for retrieving reference data in OverkizClient
iMicknl Jan 27, 2026
13a4aa7
Add missing enum values and improve formatting in enums
iMicknl Jan 27, 2026
3ea520b
Enhance Protocol handling: add ProtocolType model, update Protocol en…
iMicknl Jan 27, 2026
8c76953
Change return type of get_reference_ui_classes to list[str] for impro…
iMicknl Jan 27, 2026
0c59873
Update UI enums: enhance documentation, reorder values, and add missi…
iMicknl Jan 27, 2026
f9527af
Fix UIClass and UIWidget enum UNKNOWN value capitalization
iMicknl Jan 27, 2026
e4abd5c
Add UIClassifier enum and update get_reference_ui_classifiers return …
iMicknl Jan 27, 2026
e1fa9cb
feat: add UIProfile enum generation from Overkiz API
iMicknl Jan 27, 2026
ad7a581
Apply suggestion from @Copilot
iMicknl Jan 27, 2026
405ec20
fix: change return type of get_reference_ui_widgets to list[str] for …
iMicknl Jan 27, 2026
bb7fdcc
feat: add UIProfileDefinition model and related classes, and implemen…
iMicknl Jan 27, 2026
3d9b11a
Address code review feedback: fix import pollution and remove redunda…
Copilot Jan 28, 2026
4648266
Update utils/generate_enums.py
iMicknl Jan 28, 2026
7f6d696
Update pyoverkiz/enums/base.py
iMicknl Jan 28, 2026
e101e39
Explicitly acknowledge _missing_ override in UnknownEnumMixin (#1929)
Copilot Jan 29, 2026
753b5cc
Bugfix
iMicknl Jan 29, 2026
d35cb80
Add command extraction and enum generation from fixture files
iMicknl Jan 29, 2026
9257adf
Add state value extraction and update OverkizCommandParam in enum gen…
iMicknl Jan 29, 2026
5dbb8ea
Regenerate uv
iMicknl Feb 15, 2026
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
72 changes: 72 additions & 0 deletions pyoverkiz/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@
Option,
OptionParameter,
Place,
ProtocolType,
ServerConfig,
Setup,
State,
UIProfileDefinition,
)
from pyoverkiz.obfuscate import obfuscate_sensitive_data
from pyoverkiz.serializers import prepare_payload
Expand Down Expand Up @@ -651,6 +653,76 @@ async def get_setup_option_parameter(

return None

@retry_on_auth_error
async def get_reference_controllable(self, controllable_name: str) -> JSON:
"""Get a controllable definition."""
return await self.__get(
f"reference/controllable/{urllib.parse.quote_plus(controllable_name)}"
)

@retry_on_auth_error
async def get_reference_controllable_types(self) -> JSON:
"""Get details about all supported controllable types."""
return await self.__get("reference/controllableTypes")

@retry_on_auth_error
async def search_reference_devices_model(self, payload: JSON) -> JSON:
"""Search reference device models using a POST payload."""
return await self.__post("reference/devices/search", payload)

@retry_on_auth_error
async def get_reference_protocol_types(self) -> list[ProtocolType]:
"""Get details about supported protocol types on that server instance.

Returns a list of protocol type definitions, each containing:
- id: Numeric protocol identifier
- prefix: URL prefix used in device addresses
- name: Internal protocol name
- label: Human-readable protocol label
"""
response = await self.__get("reference/protocolTypes")
return [ProtocolType(**protocol) for protocol in response]

@retry_on_auth_error
async def get_reference_timezones(self) -> JSON:
"""Get timezones list."""
return await self.__get("reference/timezones")

@retry_on_auth_error
async def get_reference_ui_classes(self) -> list[str]:
"""Get a list of all defined UI classes."""
return await self.__get("reference/ui/classes")

@retry_on_auth_error
async def get_reference_ui_classifiers(self) -> list[str]:
"""Get a list of all defined UI classifiers."""
return await self.__get("reference/ui/classifiers")

@retry_on_auth_error
async def get_reference_ui_profile(self, profile_name: str) -> UIProfileDefinition:
"""Get a description of a given UI profile (or form-factor variant).

Returns a profile definition containing:
- name: Profile name
- commands: Available commands with parameters and descriptions
- states: Available states with value types and descriptions
- form_factor: Whether profile is tied to a specific physical device type
"""
response = await self.__get(
f"reference/ui/profile/{urllib.parse.quote_plus(profile_name)}"
)
return UIProfileDefinition(**humps.decamelize(response))

@retry_on_auth_error
async def get_reference_ui_profile_names(self) -> list[str]:
"""Get a list of all defined UI profiles (and form-factor variants)."""
return await self.__get("reference/ui/profileNames")

@retry_on_auth_error
async def get_reference_ui_widgets(self) -> list[str]:
"""Get a list of all defined UI widgets."""
return await self.__get("reference/ui/widgets")

async def __get(self, path: str) -> Any:
"""Make a GET request to the OverKiz API."""
await self._refresh_token_if_expired()
Expand Down
50 changes: 40 additions & 10 deletions pyoverkiz/enums/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
"""Convenience re-exports for the enums package."""

# flake8: noqa: F403
# Explicitly re-export all Enum subclasses to avoid wildcard import issues
from pyoverkiz.enums.command import CommandMode, OverkizCommand, OverkizCommandParam
from pyoverkiz.enums.execution import (
ExecutionState,
ExecutionSubType,
ExecutionType,
)
from pyoverkiz.enums.gateway import GatewaySubType, GatewayType, UpdateBoxStatus
from pyoverkiz.enums.general import DataType, EventName, FailureType, ProductType
from pyoverkiz.enums.measured_value_type import MeasuredValueType
from pyoverkiz.enums.protocol import Protocol
from pyoverkiz.enums.server import APIType, Server
from pyoverkiz.enums.state import OverkizAttribute, OverkizState
from pyoverkiz.enums.ui import UIClass, UIClassifier, UIWidget
from pyoverkiz.enums.ui_profile import UIProfile

from .command import *
from .execution import *
from .gateway import *
from .general import *
from .measured_value_type import *
from .protocol import *
from .server import *
from .state import *
from .ui import *
__all__ = [
"APIType",
"CommandMode",
"DataType",
"EventName",
"ExecutionState",
"ExecutionSubType",
"ExecutionType",
"FailureType",
"GatewaySubType",
"GatewayType",
"MeasuredValueType",
"OverkizAttribute",
"OverkizCommand",
"OverkizCommandParam",
"OverkizState",
"ProductType",
"Protocol",
"Server",
"UIClass",
"UIClassifier",
"UIProfile",
"UIWidget",
"UpdateBoxStatus",
]
27 changes: 27 additions & 0 deletions pyoverkiz/enums/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Shared enum helpers for consistent parsing and logging."""

from __future__ import annotations

import logging
from typing import Self, cast


class UnknownEnumMixin:
"""Mixin for enums that need an `UNKNOWN` fallback.

Define `UNKNOWN` on the enum and optionally override
`__missing_message__` to customize the log message.
"""

__missing_message__ = "Unsupported value %s has been returned for %s"

@classmethod
def _missing_(cls, value: object) -> Self: # type: ignore[override]
"""Return `UNKNOWN` and log unrecognized values.

Intentionally overrides the Enum base `_missing_` to provide an UNKNOWN fallback.
"""
message = cls.__missing_message__
logging.getLogger(cls.__module__).warning(message, value, cls)
# Type checker cannot infer UNKNOWN exists on Self, but all subclasses define it
return cast(Self, cls.UNKNOWN) # type: ignore[attr-defined]
Loading