Add OCF-spec-confirmed oic.d types: airpurifier, dishwasher, oven

Extend _OIC_TYPE_TO_KEY with three more device categories the OCF Smart
Home Device Specification defines with the same 'oic.d.<category>' shape
as the already-confirmed entries, ahead of seeing them in an actual dump.
Deliberately leave out the rest of a broader compiled oic.d/x.com.st.d
list (lights, switches, sensors, locks, cameras, TVs, generic energy
meters, oic.d.robotcleaner, ...) -- none of those map to a registry this
integration has, and robotcleaner in particular names a different product
than the vacuum_station clean-station registry.
This commit is contained in:
Marc Billow
2026-07-31 00:58:26 +00:00
parent 4f9e630ae9
commit 0a4b80afc4
2 changed files with 41 additions and 6 deletions
@@ -193,15 +193,39 @@ def _consumer_model_key(description: str) -> Optional[str]:
# -> registry key. This is the device naming its own type -- no board-part
# guessing involved -- so it's consulted before modelNum/description at all.
#
# Kept as narrow as the board-token table: every entry here is backed by a
# real dump/issue, not a guess at what the OCF or SmartThings spec might
# define. `x.com.st.d.*` entries are SmartThings' own vendor extension to
# the OCF device-type vocabulary (used for categories with no `oic.d.*`
# equivalent), same prefix convention as the `x.com.samsung.da.*` resource
# fields elsewhere in this codebase.
# Two provenance tiers, marked per entry:
# - "issue #N" -- seen verbatim in a real dump.
# - "OCF spec" -- not seen in a dump yet, but the OCF Smart Home Device
# Specification's Table 9-1 defines this exact `oic.d.*` string for this
# exact appliance category, and it's the same 'oic.d.<category>' shape
# as every issue-confirmed entry above it. Low-risk to add ahead of a
# dump precisely because that shape leaves no plausible alternative
# reading -- unlike a board-token table entry, there's no tokenizing or
# delimiter-spelling judgment call involved.
#
# Every value must already be a key in `_REGISTRY_BY_KEY` (checked by
# `test_every_oic_type_resolves_to_a_real_registry`). That's why this list
# stops well short of the full OCF/SmartThings device-type vocabulary: a
# compiled list of `x.com.st.d.*` types will include plenty of device
# categories (lights, switches, sensors, locks, cameras, TVs, generic energy
# meters, ...) no Samsung DA appliance dump could ever report and this
# integration has no registry for -- and 'oic.d.robotcleaner' names an
# actual robot vacuum, a different product from the clean/auto-empty
# *station* `vacuum_station` covers (see that registry's own module
# docstring); mapping it there would misroute a genuine robot-vacuum dump
# into a registry with no vacuum-body capabilities at all. Add a row only
# once there's a real registry key on the right-hand side to point at.
#
# `x.com.st.d.*` entries are SmartThings' own vendor extension to the OCF
# device-type vocabulary (used for categories with no `oic.d.*` equivalent),
# same prefix convention as the `x.com.samsung.da.*` resource fields
# elsewhere in this codebase.
_OIC_TYPE_TO_KEY: dict[str, str] = {
'oic.d.airconditioner': 'airconditioner',
'oic.d.airpurifier': 'air_purifier', # OCF spec
'oic.d.dishwasher': 'dishwasher', # OCF spec
'oic.d.dryer': 'dryer',
'oic.d.oven': 'oven', # OCF spec
'oic.d.refrigerator': 'refrigerator',
'oic.d.washer': 'washer',
'x.com.st.d.stickcleaner': 'vacuum_station', # issue #219 -- stick-vacuum clean station
+11
View File
@@ -143,7 +143,10 @@ class TestForDeviceByOicType:
@pytest.mark.parametrize('oic_type, expected', [
('oic.d.airconditioner', 'airconditioner'),
('oic.d.airpurifier', 'air_purifier'),
('oic.d.dishwasher', 'dishwasher'),
('oic.d.dryer', 'dryer'),
('oic.d.oven', 'oven'),
('oic.d.refrigerator', 'refrigerator'),
('oic.d.washer', 'washer'),
('x.com.st.d.stickcleaner', 'vacuum_station'),
@@ -165,6 +168,14 @@ class TestForDeviceByOicType:
from custom_components.localthings.registry.by_type import for_device_by_oic_type
assert for_device_by_oic_type(('oic.d.somethingnew',)) is None
def test_robotcleaner_is_not_mapped_to_the_vacuum_station_registry(self):
"""'oic.d.robotcleaner' names an actual robot vacuum, a different
product from the clean/auto-empty station vacuum_station covers (no
vacuum-body capabilities at all) -- mapping it there would misroute
a genuine robot-vacuum dump."""
from custom_components.localthings.registry.by_type import for_device_by_oic_type
assert for_device_by_oic_type(('oic.d.robotcleaner',)) is None
def test_empty_returns_none(self):
from custom_components.localthings.registry.by_type import for_device_by_oic_type
assert for_device_by_oic_type(()) is None