refactor: move samsung_appliance/ into custom_components/localthings/ocf/

Makes the integration fully self-contained for HACS distribution.
Users installing via HACS get everything in one directory; no external
samsung_appliance package needed.

All component imports updated to relative (.ocf.*); all test imports
updated to custom_components.localthings.ocf.*. ocf_root_ca.pem moves
with the package and resolves correctly via Path(__file__).parent.
This commit is contained in:
Marc Billow
2026-06-30 16:34:20 -05:00
parent 0bb27a9204
commit cc2c1e5a1f
50 changed files with 50 additions and 50 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ certs/
*.key
# Exception: bundled Samsung OCF Root CA (public cert, no key material)
!samsung_appliance/ocf_root_ca.pem
!custom_components/localthings/ocf/ocf_root_ca.pem
token.txt
# Python artifacts
@@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from samsung_appliance.registry.entities import BinarySensorDesc
from .ocf.registry.entities import BinarySensorDesc
from .const import DOMAIN
from .coordinator import LocalThingsCoordinator
+2 -2
View File
@@ -26,8 +26,8 @@ def _probe_and_validate(host: str, cert_pem: str, key_pem: str) -> dict:
to a temp-file pair and cleaned up in the finally block.
"""
import cbor2
from samsung_appliance.coap_dtls import DtlsCoapSession
from samsung_appliance.batch import parse_device0_batch
from .ocf.coap_dtls import DtlsCoapSession
from .ocf.batch import parse_device0_batch
# Write PEM strings to temporary files — DtlsCoapSession requires
# cert_path / key_path rather than in-memory PEM strings.
+7 -7
View File
@@ -14,13 +14,13 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.helpers.device_registry import DeviceInfo
from samsung_appliance.batch import parse_device0_batch
from samsung_appliance.coap_dtls import DtlsCoapSession
from samsung_appliance.registry.by_type import for_device
from samsung_appliance.registry.discovery import discover, BoundEntity
from samsung_appliance.registry import CAPABILITIES
from samsung_appliance.registry.adapter import flatten, is_active
from samsung_appliance.registry.identity import read_identity, DeviceIdentity
from .ocf.batch import parse_device0_batch
from .ocf.coap_dtls import DtlsCoapSession
from .ocf.registry.by_type import for_device
from .ocf.registry.discovery import discover, BoundEntity
from .ocf.registry import CAPABILITIES
from .ocf.registry.adapter import flatten, is_active
from .ocf.registry.identity import read_identity, DeviceIdentity
from .const import (
DOMAIN, CONF_HOST, CONF_PORT, CONF_CERT_PEM, CONF_KEY_PEM,
+2 -2
View File
@@ -4,8 +4,8 @@ from __future__ import annotations
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.helpers.device_registry import DeviceInfo
from samsung_appliance.registry.adapter import _key
from samsung_appliance.registry.discovery import BoundEntity
from .ocf.registry.adapter import _key
from .ocf.registry.discovery import BoundEntity
from .const import DOMAIN
from .coordinator import LocalThingsCoordinator
+1 -1
View File
@@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from samsung_appliance.registry.entities import NumberDesc
from .ocf.registry.entities import NumberDesc
from .const import DOMAIN
from .coordinator import LocalThingsCoordinator
@@ -1,4 +1,4 @@
"""Samsung appliance local-API library.
"""Samsung appliance local-API library (custom_components/localthings/ocf).
CoAP/DTLS session management, OCF batch resource parsing, and a
capability registry for discovering and reading Samsung appliance state."""
+1 -1
View File
@@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from samsung_appliance.registry.entities import SelectDesc
from .ocf.registry.entities import SelectDesc
from .const import DOMAIN
from .coordinator import LocalThingsCoordinator
+1 -1
View File
@@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from samsung_appliance.registry.entities import SensorDesc
from .ocf.registry.entities import SensorDesc
from .const import DOMAIN
from .coordinator import LocalThingsCoordinator
+1 -1
View File
@@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from samsung_appliance.registry.entities import SwitchDesc
from .ocf.registry.entities import SwitchDesc
from .const import DOMAIN
from .coordinator import LocalThingsCoordinator
+1 -1
View File
@@ -7,7 +7,7 @@ FIXTURES = Path(__file__).resolve().parent / 'fixtures'
def _resources_from_dump(dump: dict) -> dict[str, dict]:
from samsung_appliance.batch import parse_device0_batch
from custom_components.localthings.ocf.batch import parse_device0_batch
return parse_device0_batch(dump['device0'])
+1 -1
View File
@@ -52,7 +52,7 @@ ENTRY_DATA = {
def _load_fridge_resources() -> dict:
from samsung_appliance.batch import parse_device0_batch
from custom_components.localthings.ocf.batch import parse_device0_batch
data = json.loads((FIXTURES / 'refrigerator_device.json').read_text())
return parse_device0_batch(data['device0'])
+1 -1
View File
@@ -1,6 +1,6 @@
"""Tests for samsung_appliance/registry/by_type."""
import pytest
from samsung_appliance.registry.by_type import _type_key, for_device, DeviceRegistry
from custom_components.localthings.ocf.registry.by_type import _type_key, for_device, DeviceRegistry
class TestTypeKey:
+4 -4
View File
@@ -4,10 +4,10 @@ from pathlib import Path
import pytest
from samsung_appliance.registry.adapter import _key
from samsung_appliance.registry.by_type import dishwasher, refrigerator
from samsung_appliance.registry.capabilities import fridge
from samsung_appliance.registry.discovery import discover
from custom_components.localthings.ocf.registry.adapter import _key
from custom_components.localthings.ocf.registry.by_type import dishwasher, refrigerator
from custom_components.localthings.ocf.registry.capabilities import fridge
from custom_components.localthings.ocf.registry.discovery import discover
from tests.conftest import _load_resources
GOLDEN = Path(__file__).parent / 'fixtures' / 'golden'
+2 -2
View File
@@ -1,5 +1,5 @@
from samsung_appliance.registry.capability import Capability
from samsung_appliance.registry.entities import BinarySensorDesc
from custom_components.localthings.ocf.registry.capability import Capability
from custom_components.localthings.ocf.registry.entities import BinarySensorDesc
def test_capability_defaults():
+2 -2
View File
@@ -1,5 +1,5 @@
from samsung_appliance.registry.capabilities import common
from samsung_appliance.registry.discovery import discover
from custom_components.localthings.ocf.registry.capabilities import common
from custom_components.localthings.ocf.registry.discovery import discover
def _reg():
+3 -3
View File
@@ -1,8 +1,8 @@
from samsung_appliance.registry.capability import Capability
from samsung_appliance.registry.discovery import (
from custom_components.localthings.ocf.registry.capability import Capability
from custom_components.localthings.ocf.registry.discovery import (
BoundEntity, discover, instance_suffix,
)
from samsung_appliance.registry.entities import BinarySensorDesc
from custom_components.localthings.ocf.registry.entities import BinarySensorDesc
LOCK = Capability(
href='/kidslock/vs/0',
+3 -3
View File
@@ -1,8 +1,8 @@
import pytest
from tests.conftest import _load_device
from samsung_appliance.registry.by_type import for_device, _type_key
from samsung_appliance.registry.discovery import discover
from samsung_appliance.registry.adapter import flatten, is_active
from custom_components.localthings.ocf.registry.by_type import for_device, _type_key
from custom_components.localthings.ocf.registry.discovery import discover
from custom_components.localthings.ocf.registry.adapter import flatten, is_active
@pytest.mark.parametrize('name,expected_type_key', [
+1 -1
View File
@@ -1,4 +1,4 @@
from samsung_appliance.registry.entities import (
from custom_components.localthings.ocf.registry.entities import (
SensorDesc, BinarySensorDesc, SelectDesc, SwitchDesc, ButtonDesc,
NumberDesc, PLATFORM_OF,
)
+3 -3
View File
@@ -7,9 +7,9 @@ pattern capability that auto-derives distinct keys from the href segments.
"""
from tests.conftest import _load_resources
from samsung_appliance.registry.adapter import _key
from samsung_appliance.registry.by_type import refrigerator
from samsung_appliance.registry.discovery import discover
from custom_components.localthings.ocf.registry.adapter import _key
from custom_components.localthings.ocf.registry.by_type import refrigerator
from custom_components.localthings.ocf.registry.discovery import discover
def test_two_doors_get_distinct_keys():
+4 -4
View File
@@ -7,14 +7,14 @@ GOLDEN = Path(__file__).parent / 'fixtures' / 'golden'
def _new_state_keys(name, resources):
from samsung_appliance.registry.by_type import for_device
from samsung_appliance.registry.discovery import discover
from samsung_appliance.registry.adapter import flatten
from custom_components.localthings.ocf.registry.by_type import for_device
from custom_components.localthings.ocf.registry.discovery import discover
from custom_components.localthings.ocf.registry.adapter import flatten
otn = resources.get('/otninformation/vs/0', {})
one_ui = otn.get('swVersionInfo', {}).get('oneUiVersion', '')
reg = for_device(one_ui) if one_ui else None
if reg is None:
from samsung_appliance.registry.registry import CAPABILITIES
from custom_components.localthings.ocf.registry.registry import CAPABILITIES
caps, pats = CAPABILITIES, []
else:
caps, pats = reg.capabilities, reg.pattern_capabilities
+1 -1
View File
@@ -1,6 +1,6 @@
import cbor2
from samsung_appliance.registry.identity import DeviceIdentity, read_identity
from custom_components.localthings.ocf.registry.identity import DeviceIdentity, read_identity
class FakeSession:
+2 -2
View File
@@ -1,6 +1,6 @@
"""Write-handler unit tests for laundry-family capabilities."""
from samsung_appliance.registry.capabilities import laundry
from samsung_appliance.registry.capabilities.operational import OPERATIONAL_STATE
from custom_components.localthings.ocf.registry.capabilities import laundry
from custom_components.localthings.ocf.registry.capabilities.operational import OPERATIONAL_STATE
def test_start_button_writes_run():
+1 -1
View File
@@ -1,5 +1,5 @@
import time
from samsung_appliance.registry.capabilities.operational import OPERATIONAL_STATE
from custom_components.localthings.ocf.registry.capabilities.operational import OPERATIONAL_STATE
def test_machine_state_maps_samsung_to_ocf():
+2 -2
View File
@@ -1,6 +1,6 @@
"""Unit tests for oven-family capabilities."""
from samsung_appliance.registry.capabilities import oven
from samsung_appliance.registry.discovery import discover
from custom_components.localthings.ocf.registry.capabilities import oven
from custom_components.localthings.ocf.registry.discovery import discover
# ---------------------------------------------------------------------------
+1 -1
View File
@@ -1,5 +1,5 @@
"""Tests for the CAPABILITIES registry."""
from samsung_appliance.registry.registry import CAPABILITIES
from custom_components.localthings.ocf.registry.registry import CAPABILITIES
def test_registry_is_keyed_by_href():