Leaving SmartThings before the October API fees: my apartment now runs on an old MacBook

Samsung announced in June that SmartThings API access goes paid in October, $4.99/month for personal use. Maybe personal tokens get an exemption, maybe the HA integration survives untouched, I honestly don’t know. But with a baby due in November I didn’t feel like betting the house on a pricing FAQ, so I spent ten days moving our whole apartment off SmartThings.

The server is the part people will yell at me about: it’s my old M1 MacBook, lid closed, kept awake with caffeinate. Yes I know, get a Pi, get a NUC. But the M1 was sitting in a drawer doing nothing, it’s completely silent, it has a built-in UPS (the battery, 210 cycles and still fine), and the full stack barely registers on it - the Stream Deck next to it shows 9.6 W package power, CPU at 68 C, fan at 1,212 rpm. The Mac itself has been up 31 days, longer than this server project has existed. The compose volumes are all relative paths, so the day I do buy a Pi 5 I copy one directory and go. Both arm64, same images.


Coordinator is a Sonoff ZBDongle-P. Stack is Home Assistant + Mosquitto + Zigbee2MQTT + Postgres under docker compose. Sounds like an afternoon of work. It was not, and macOS was the reason, twice.

First trap: the HA image wouldn’t unpack. invalid tar header, right at the end of a 100% completed download, which looks exactly like a broken network. I re-pulled it three times before checking the actual cause: HA ships its layers as tar+zstd, and Docker older than 23.0 doesn’t know zstd, so it assumes gzip and dies at the last moment. My Docker Desktop was an ancient 20.10. I ended up on colima rather than upgrading Desktop, which brought its own comedy: the Mac now has two docker binaries and the dead one comes first in PATH.

Second trap, and this one has no workaround: you cannot pass a USB device into a container on macOS. Docker Desktop and colima both run containers inside a VM, and the dongle simply doesn’t exist in there. So Zigbee2MQTT runs natively on the host, outside compose, pointed at the same data directory the container would use (so the pairings survive the eventual Pi move without re-pairing 20 devices).

And then, with everything finally in place, I plugged in the dongle and Z2M died on startup. Every single time, getExtAddr timeout. I probed the dongle by hand with raw serial commands to prove it wasn’t bricked (it wasn’t). The real cause took three evenings to find, it’s buried in zigbee-herdsman, and it’s darkly funny - the fix was a 60-line Python script and I’ll write it up later in this thread because it deserves the space. (The post right after this one is about the wallpad, the Korean apartment panel that owns my ceiling lights and, as it turns out, the elevator.)

After that it was two weekends of room-by-room migration, 18 devices the first weekend and the stragglers after. One thing I didn’t expect: several sensors got better after leaving. My bathroom “motion sensor” turned out to be a 4-in-1 that exposes a presence channel the SmartThings driver never showed me.

The ST hub is off now. Automations are in HA, history is in Postgres, and the wallpad (Korean apartment RS-485 thing) is a separate saga I’ll get to.

A few weeks in, a verdict I didn’t plan on giving: I’m a little bit in love with HA. I braced for the YAML horror stories and instead most of it was a config flow and a click. And to be fair to SmartThings, it has the prettier app, but pretty was never my problem. The moment you want to touch anything programmatically it fights you, and that’s exactly the layer that’s about to get a price tag.

The one ST screen I did miss was the Map View. Here’s what it looked like in July:

Pretty, right? This is the part ST genuinely does well. So I rebuilt the idea in HA as a floorplan dashboard: live temperature, lights and presence per room, plus the four buttons we actually use. One of those calls the elevator, which is the wallpad post’s problem to explain.

Anyone else jumping before October, or are you waiting to see where the fee actually lands?

P.S. Apologies that every screen in the photos is in Korean :slight_smile: the wallpad post will be worse.

I switched my primary location from SmartThings to Home Assistant about a month ago. I used a Beelink mini PC. Works well.

My second location remains on SmartThings for the time being. But I will remove any integrations that will trigger a fee.

Not aware of LocalThings (yet) :thinking: ?

Nice, a Beelink is basically the Pi-adjacent path I’ll end up on too, so it’s good to hear it’s been solid a month in. For anyone on the fence, that’s the boring-and-correct choice next to my “old MacBook with the lid closed” setup. I just happened to have the M1 sitting idle, and it’s also running a couple of AI agents on the side, so it earns its keep.

How are you deciding which integrations to pull at the second location? Going by Samsung’s published list of what gets metered, or waiting to see what actually breaks in October? I haven’t found a clean answer on that myself.

I wasn’t, and I just went down that rabbit hole, so thank you. For anyone else reading: LocalThings talks to newer Samsung appliances locally over CoAP-DTLS, no cloud involved, so the October change doesn’t touch it. Timely for me - my washer and fridge are both still hanging off the old cloud integration and sit there unavailable right now. I’ll have to check what firmware they’re on before getting my hopes up, but I’m going to give it a go this weekend and report back either way.

I currently have SmartThings (ST) at my 2nd location connected to Home Assistant (HA) at my Primary location to monitor things using HA dashboards. I know this Home Assistant will integration will trigger the SmartThings fee so I will be disconnected that before 10/1.

SharpTools has said their integration will NOT trigger the SmartThings fee so I will be keep that. But they are applying rate limits to control their corporate Smartthings fees

I am not sure about my other ST integrations (Tuya, SwitchBot, Meross, Tapo, August, IFTTT). I guess I will find out later this month what I will keep or drop due to the fee.

Eventually I hope to convert my 2nd location to HA.

The second-location case is the one I’d struggle with too. Everything I moved off SmartThings is local now, but the reason I could do that is that the house and the server are in the same building. If you do put a second HA at that site, the piece that made two locations feel like one for me was a ZeroTier network between the boxes, so the remote instance shows up on the main dashboard as if it were on the LAN, no port forwarding.

I haven’t figured the out yet. The following is one Gemini’s suggestions:

That one sits on top of what I described rather than replacing it. It connects to the remote instance’s websocket API and forwards service calls back, so it still needs to reach that box in the first place, which is the part the overlay network handles. Worth reading before you set it up: there’s a thread on the front page right now where someone put the token on both instances instead of just the main one, and the two of them re-imported each other into 55,000 entities that HA then refused to delete. I haven’t run it myself, so that’s as far as I can help.

Follow-up on the LocalThings tip, since I said I would report back. It worked: the fridge went local about twenty minutes after I put the integration in, and it gives me 28 entities where the cloud one gave 13. One day in, it has not gone unavailable even once, 1,194 power readings between 3 and 273 W, 37 door opens recorded. The washer is a different story, it simply refuses the handshake, because the 2025 laundry firmware trusts a different root than the certificate this integration signs with, and that is an open issue upstream (localthings #435). So one of the two is off the cloud, and it happens to be the one I cared about more. Thank you for pointing me there.

Hmm, that surprises me a little…according the dev only the older firmware’s aren’t supported :thinking:

This needs an appliance on Tizen RT 3.x / DAWIT 3.0+ firmware (roughly 2022+), which exposes a local DTLS-CoAP API. Older firmware (roughly 2018-2022) only talks to Samsung’s cloud over token-based HTTPS and isn’t supported

But maybe this is not a Tizen RT 3.x / DAWIT 3.0+ firmware ?

According my ‘friend’ (chatGPT):

  1. ~2022 onward: newer appliances use Tizen RT 3.x / DAWIT 3.0+, with local CoAP over DTLS on UDP 49152–49160.
  2. 2025/2026 dryers: I don’t see evidence that Samsung has moved dryers to a fundamentally new firmware platform beyond the DAWIT 3.x / Tizen RT family. There can of course be newer firmware builds/versions within that family.

Edit:…oh, I see the issue now…Architecture: PSK and server-authenticated OCF device support · Issue #435 · mbillow/localthings · GitHub

@sglim Regarding the map view. Zircon3D is great…

But i am working on something better than picture elements and easy to set up, currently i have an card for robot vcauum that supports adding furniture to the map: [Card] VacuumCard-ADV 2.1.0 — an advanced Card for Robot Vacuums, including furniture placement and room select

Right, that is the part that confused me at first too. Mine is not an old-firmware case at all: it answers on UDP 49154 and comes back with a DTLS handshake_failure alert, so it is clearly speaking the local protocol, it just will not accept a client certificate. The 2025 laundry models look server-authenticated with no client leaf, which is a different axis from the firmware age in the README, and #435 is exactly that.

I do have one, an X50 Pro Master, but it is not in Home Assistant at all: mine sits on firmware 4.3.9_2532 and Matter never shows up. Dreame support told someone the Matter firmware shipped on 5 December 2025 and that they cannot push it remotely, and in that thread people were still stuck on 4.3.9_2908 in March: Reddit

So it looks like a slow rollout rather than a missing build. I am in Korea, and my guess is that per-country approval is part of why it is late here, but that is a guess and not something I can show you. Either way I cannot try your card yet. What I keep wanting on a floorplan anyway is live radar coordinates, my LD2450 gives x and y in millimetres for up to three targets, and picture-elements is the only way I found to place them, so if the furniture placement takes arbitrary coordinates it would cover my case too.

A used Intel NUC i3 on eBay is much cheaper than a new Raspberry Pi5 and the NUC will outperform the Pi in every performance parameter.

I can take a look if it would be possible to integrate your Dreame X50 to h.a.
Would you be open to some traffic sniffing(between your vacuum and router)?

You are right on price and raw speed, and if I were starting from scratch I would probably look at one. The reason I wrote Pi 5 specifically is that my recorder is PostgreSQL, and a Postgres data directory is not portable across architectures, so arm64 to arm64 is a copy while arm64 to x86 is a dump and restore. That is a one-off either way, but it is the difference between moving the server on a weekday evening and setting aside a Saturday.

Followed up on the Dreame idea myself before sending you anything. On an R2501P (X50 line) the Dreamehome app does everything through the cloud: I isolated the robot on its own AP and it only ever talks to Alibaba, a custom TLS service on port 19973 and MQTT-over-TLS on 1883, nothing local at all. Even with an mDNS reflector running, the app never sends a single packet straight to the robot, so there is no LAN protocol to sniff in the first place. That also lines up with the Tasshack integration stopping at X10, and with the note that the Dreamehome app disables the local API. So the only real paths look like rooting it with Valetudo or waiting for the Matter firmware Dreame keeps saying is coming. I will spare you the packet capture since there is genuinely nothing local in it, but happy to compare notes if you have cracked the app side.

The follow-up above was the short version. This is the part that took the actual
afternoon.

Finding the appliances was the first problem. They don’t answer SSDP, and the
router’s client list gives you a MAC and nothing else. What works is throwing a
DTLS ClientHello at UDP 49152-49160 across the subnet and seeing who alerts
back. Two hosts answered on 49154. That the washer answered at all is the only
reason I could later tell its failure was about certificates rather than
firmware age.

Then the thing I expected to be a problem wasn’t. The README says you need
network_mode: host, because DTLS is UDP and won’t cross Docker’s bridge NAT.
My HA runs in a colima VM behind two layers of NAT, and both appliances
answered from inside the container anyway. Client-initiated UDP traverses NAT
the same way TCP does, the reply just follows the mapping back. That’s the
mirror image of trap two in the first post: USB cannot cross the VM boundary,
UDP sessions you open yourself can.

The fridge is not a clean sweep either. Two of the 28 entities stay empty, the
night light start and end times, which the appliance apparently does not report
at all. Everything else is live, including a self-check that comes back with an
actual result rather than a status you have to interpret.

One more thing worth admitting. The first-device setup needs an intermediate CA
certificate and its key, which the tool fetches from a public mirror. The AI
agent I run on that server refused to touch the step, twice, on the grounds
that it looked like downloading someone’s private key and using it to
authenticate to a device. Fair enough, honestly. I ran that one command myself,
handed the result to the config flow, done. I think that’s the right split.

Worth saying out loud: this is a community project, not Samsung’s, built by
reading the open-source Tizen RT firmware, and there is no reason Samsung has
to like it. The laundry line moving to a different PKI this year might be
exactly that. So I’m enjoying the fridge while it lasts and not deleting the
cloud integration yet.

Next up is the wallpad, and the elevator.

App-Router sniffing always shows you the cloud.
Only router-vacuum sniffing is useful, because the vacuum must eventually receive a command, even if it is signed by the cloud (and not sendable locally) or I do not know what; it still must be received.