Adds [tool.ruff] and [tool.ty] config to pyproject.toml with a curated
ruff rule set (E, F, W, I, UP, B, C4, SIM, RUF, ASYNC, LOG, G, PIE, RET,
PERF, N), pins ruff/ty in requirements-dev.txt, reformats the whole tree
with `ruff format`, and fixes the pre-existing lint and type-check debt
those tools surfaced so both run clean.
Production-code type fixes include: HA's ConfigFlowResult vs. the
generic FlowResult in config_flow.py, narrowing BoundEntity.desc to its
platform-specific subclass (SelectDesc/NumberDesc/SensorDesc/etc.) via
cast() instead of an unchecked annotation, converting HA device_class
strings to their proper enum types, a resolve_registry callback typed
as `object` instead of `DeviceRegistry | None`, and a couple of other
narrow correctness fixes (CA key type validation, an index-out-of-bounds
false positive from an empty-tuple fallback, a bool/dict argument swap).
Test-file fixes are mechanical: narrowing SamsungEntityDescription to
the correct subclass via isinstance()/cast() before accessing
subclass-only fields, and asserting Optional write_fn/unit_fn fields
are set before calling them.
- Pin the FAN_ONLY reverse-write fallback to 'Wind' (the original single
spelling) instead of letting it silently flip to 'Fan' just because
'Fan' was added second to the dict -- _device_code_for_hvac() resolves
the code from a unit's own supportedModes first, so this dict is only
a fallback for a unit reporting none at all, and that fallback
shouldn't change behavior as an unintended side effect of insertion
order.
- Add direct tests for _preset_to_ha() (pure function, previously
untested) and the FAN_ONLY fallback pin.
- Cross-reference the AC family's inverted Light_On/Light_Off polarity
against air_purifier.py's plain-polarity use of the same token name on
the same resource name, so a future refactor doesn't assume they're
the same thing.
- Fix a one-column continuation-line misalignment and a stale PR-number
reference in a comment.
Three gaps reported against an ARTIK051_PRAC_20K WindFree unit vs. the
SmartThings integration:
1. Missing WindFree/motion convenient-mode presets -- left alone here.
PR #91 replaces climate.py's static _DEVICE_TO_PRESET table with a
generic resolver that reads any preset code straight off the unit's
own supportedModes, which already covers this (and more generically
than a per-model dict would) -- adding one here would just conflict.
2. No horizontal oscillation: /wind/direction/vs/0's supportedModes
includes Left_And_Right, which _DEVICE_TO_SWING had no mapping for.
Add it to HA's standard 'horizontal' swing constant.
3. No standalone humidity/current-temperature sensors: the climate card
already reads both internally, but nothing exposed them as entities
for history/automations. Add CURRENT_TEMPERATURE (OCF
/temperature/current/0) with a CURRENT_TEMPERATURE_VS vendor fallback
(same match_fn-gated pair shape as common.py's POWER_GENERIC/
POWER_VS_FALLBACK), and a HUMIDITY sensor reading /humidity/vs/0's
fivepercentHumidity field -- the only one of the three
humidity-shaped fields across /humidity/0 and /humidity/vs/0 that
isn't permanently stuck at 0 on every dump seen.
Regenerates the five existing AC goldens (all pick up
current_temperature_c; most pick up humidity) and adds a dedicated
fixture from the issue's WindFree dump, whose /humidity/vs/0 actually
has live fivepercentHumidity data.