Two problems, one setup path. Port detection (issue #211): the config flow found the DTLS port by elimination -- a 1-byte UDP probe can't tell a silent port from a real DTLS server, so every port it couldn't rule out got a full certificate handshake, and every false positive cost the whole 12s HANDSHAKE_TIMEOUT_S before the next was tried. Adding an appliance took 30-40s. smartthings-local 0.1.2 ships a stateless ClientHello probe that settles this positively: a real DTLS server answers with a HelloVerifyRequest in ~1 RTT, and per RFC 6347 4.2.1 it does so without allocating association state, so the probe leaves nothing behind on the appliance. The whole 49152-49160 range is probed at once and exactly one confirmed port is given a certificate handshake. Fanning out is safe here in a way racing real handshakes is not -- each probe is bounded by a 3s budget, so the pool costs one probe's wall clock rather than the sum of the range, with no losing threads left running behind us. The UDP sweep stays as the fallback for when the probe confirms nothing: it errs in the opposite direction (it reports everything it can't rule out), so it still surfaces a device on a path that eats our ClientHello, and it keeps its issue #192 preferred-port rescue. Port detection now runs first and needs no credentials, so an unreachable host fails before any round trip to Samsung's cloud. And a second appliance reuses the existing entry's leaf cert rather than re-minting -- every device accepts the same one -- which makes adding one independent of Samsung-cloud reachability. A confirmed-live device rejecting the reused leaf (the UUID does rotate) re-mints and retries once, so reuse stays self-correcting; a timeout doesn't, since a fresh cert can't fix nothing answering. Identity (issue #236): the coordinator seeded device_serial with the configured host and only replaced it after the first successful poll. But device_serial mints *permanent* registry keys -- entity unique_ids and device identifiers -- so anything registering before that poll returned was written into the registry keyed on the IP address forever. The connection-mode sensor is added unconditionally rather than from `bound`, so it was the reliable victim: when the serial-keyed identity appeared moments later HA created a second device and entity, and the IP-keyed pair was orphaned. Deleting them didn't help; the next restart that lost the race recreated them. The probe already learns the identity, so store it on the config entry -- serial, model, manufacturer, device type. The coordinator seeds device_serial and its DeviceInfo from those at construction, so keys are correct from the first entity that registers even if the first poll is slow or fails outright. There is no placeholder left to correct. Discovery now treats the registered identity as authoritative rather than re-keying a device that already has registry entries; it adopts and persists the polled identity only for an entry that has none, and warns if a different appliance answers on the same IP. Entry version 1 -> 2 recovers the serial from the entry's unique_id (the flow has always keyed it on the probe's serial) and repairs what the old registration orphaned: IP-keyed devices and entities are rewritten in place where the serial-keyed key is free -- keeping entity_id, name, area and every automation referencing them -- and removed where both exist, since the IP-keyed one has been dead since the restart that made it. Placeholder-serial boards (issues #83/#189) were keyed two ways at once, `host:port` on the entry and `host` in the registry; migration collapses the entry onto the registry's form. One resolve_serial() now serves both sides, so they can't drift apart again. The remaining step in the desired pipeline -- probe for subdevices, then register devices, then populate entities -- already holds: _enumerate_subdevices_blocking runs before _run_discovery, which runs before platforms are forwarded. Duplicating it in the config flow would mean re-running Pattern B's per-href fallback probe, which is the opposite of what issue #211 is about.
10 lines
511 B
Docker
10 lines
511 B
Docker
FROM ghcr.io/home-assistant/home-assistant:stable
|
|
|
|
# Home Assistant normally installs a custom integration's manifest.json
|
|
# requirements itself at integration setup, but that depends on the
|
|
# container having outbound network access at exactly that moment and
|
|
# repeats the install attempt on every container recreate. Baking
|
|
# smartthings-local into the image keeps the dev container usable
|
|
# offline and avoids relying on that runtime install path.
|
|
RUN pip3 install --no-cache-dir "smartthings-local>=0.1.2"
|