Commit Graph

3 Commits (624de521c4ee03ff1741da43b4466d65a784d5f3)

Author SHA1 Message Date
SchiZzA 624de521c4
feat(wslink): implement every sensor the WSLink API v0.6 defines
Coverage went from 54 of 107 upload parameters to all 107, adding roughly 34
entities. New families: Type5 lightning, Type6 water leak (CH1-7), Type8
particulate matter, Type10 CO2 and Type11 CO, plus the parameters missing from
existing families - absolute pressure, feels-like temperature, the 10-minute
average wind speed, and the per-channel probe type.

Device classes follow Home Assistant's own list (PM25, PM10, AQI, CO2, CO,
DISTANCE, ATMOSPHERIC_PRESSURE, WIND_SPEED, and binary MOISTURE for leaks), so
the readings work with statistics and unit conversion without template helpers.

Batteries were the trap. The API annotates two incompatible conventions -
"(Normal=1, Low battery=0)" and "(0~5) remark: 5 is full" - and mixing them up is
silent, because a level battery read as a flag reports "not low" for every level
above empty. Eight new binary batteries (t5lsbat, t6c1-7bat) and three new level
batteries (t8bat, t10bat, t11bat) are classified from the document, and
tests/test_wslink_api_coverage.py pins each one to the wording it came from.

Water leak and battery use opposite conventions in the same family (leak 1 means
wet, battery 0 means low), so `on_value` moved into the description and one
entity class now serves both instead of two that differ by a comparison.

`t1cn` was in the API but wired to nothing, so a disconnected outdoor probe kept
publishing its last readings. Gating it required fixing the gate first: an absent
connection flag was treated as "disconnected", which would have blanked
temperature, wind and rain outright on any firmware that omits `t1cn`. Absence is
now treated as no information, and only an explicit non-1 drops the readings.

The probe type (`t234cXtp`) decides whether a channel's humidity reading is air
humidity or soil moisture, which are different device classes. It is resolved
once, when the entity is created, because Home Assistant records the device class
in the entity registry; swapping the physical probe means reinstalling.

Two parameters are handled with a documented caveat: `inbat` is the only battery
whose scale the API does not state and stays a 0/1 flag, and `t5lst` has no unit
(the vendor example uses 9999) so it is read as minutes with 9999 meaning
"nothing recorded".

Also replaces the now-stale TODO block in const.py - it listed exactly these
sensors as unimplemented - and documents the complete coverage in the README.
2026-07-26 15:20:07 +02:00
SchiZzA 7c9343f90d
fix(sws12500): harden credential validation, URL fallback and push timeouts
- Reject blank or whitespace-only PWS credentials in both the config flow and
  the options flow. INVALID_CREDENTIALS only held placeholder strings, so an
  empty API ID or key passed validation, the entry was created, and
  _validate_credentials then rejected every incoming packet.
- Fall back to "UNKNOWN" host/port when get_url raises NoURLAvailableError.
  The values are shown as Ecowitt setup instructions only, so an unresolvable
  Home Assistant URL must not make the step unreachable.
- Catch TimeoutError alongside ClientError in the Windy and Pocasi push paths.
  A timeout is not a ClientError and used to escape into the webhook handler,
  answering the station with HTTP 500 even though the measured data was
  already stored.
- Add regression tests for all three and pin that 0-5 battery descriptions
  really reach the WSLink sensor platform.
2026-07-26 00:39:15 +02:00
SchiZzA 5adc684558
refactor(sws12500): centralize battery sensor classification 2026-07-25 23:24:45 +02:00