[ST Edge] WiFi Presence SD – phone presence by home WiFi (no GPS, no app)

Hi all :waving_hand:

I’d like to share a new Edge driver: WiFi Presence SD :satellite_antenna::house:

It detects family members’ presence by checking whether their phone is connected to the home WiFi. No GPS, no app on the phone, no Tasker. It works great in apartments, where GPS geofencing is unreliable :office_building:

:sparkles: Features

:white_check_mark: Runs 100% locally on the hub, no cloud :cloud::cross_mark:
:white_check_mark: Works with any phone (Android :robot: / iPhone :green_apple:)
:white_check_mark: Arrival detected in ~30 seconds :high_voltage:
:white_check_mark: Supports multiple SSIDs on the same network (2.4G / 5G / extenders) :antenna_bars:
:white_check_mark: Built-in Learn mode: no need to find or type the phone’s IP :graduation_cap:
:white_check_mark: Standard presenceSensor, usable in Routines, Rules API, SharpTools :robot:

:hammer_and_wrench: Installation

:one: Enroll your hub in my channel and install WiFi Presence SD:
:backhand_index_pointing_right: SmartThings. Add a little smartness to your things.
:two: In the app: Add device → Scan nearby. A “WiFi Presence 1” device is created.
:three: Rename it (e.g. “Dana’s phone”) :pencil:
:plus: More family members: open any presence device → Settings → turn Add another phone ON, then OFF. A new device is created :family_man_woman_girl:

:locked: Important: use a fixed MAC address on the phone

:mobile_phone: Samsung: WiFi → :gear: next to the network → View more → MAC address type → Phone MAC
:green_apple: iPhone: WiFi → ⓘ next to the network → Private Wi-Fi Address → Off
:backhand_index_pointing_right: Do this for every home network (SSID)

:graduation_cap: Learn the phone

:one: Turn the phone’s WiFi OFF :mobile_phone_off:
:two: In the device, turn Learn phone ON :radio_button:
:three: Wait for “Turn WiFi ON now”, then turn WiFi on :antenna_bars:
:four: When “Got .xxx” appears, switch to your next home network (if any) :repeat_button:
:five: Turn Learn phone OFF. Done! :tada:

The Learn status line guides you through each step, and Learned IPs shows what was learned (up to 6 addresses per phone).

:gear: Settings

:stopwatch: Away after (minutes): delay before “Not present” (default 10, avoids false “away” while a phone sleeps)
:label: IP labels: name each IP, e.g. 119=2.4G, 136=5G
:prohibited: Ignore IPs during Learn: other devices that join the network while learning
:broom: Clear learned IPs: start over
:plus: Add another phone: create a device for another family member

:magnifying_glass_tilted_left: How it works

Every 30 seconds the hub tries a TCP connection to the phone’s learned IP(s). Any reply, even “connection refused”, means the phone is on the network. Learn mode scans the subnet with the phone’s WiFi off, then catches the new device that appears when WiFi comes back on.

:warning: Limitations: the phone must be on the same subnet as the hub. Some phones drop WiFi in deep sleep, which is why the away delay exists.

:link: Links

:satellite_antenna: Channel: SmartThings. Add a little smartness to your things.
:laptop: Source & docs: SmartThings/drivers/wifi-presence-sd at main · dotanshai/SmartThings · GitHub

:hot_beverage: If you find it useful: https://buymeacoffee.com/dotan_shai

Feedback and questions are welcome :backhand_index_pointing_down::blush:

Some screenshot

  1. :gear: Settings

  2. 1st use, no IP addresses. :graduation_cap: Learn mode. Learn Phone turn ON, WiFi OFF. Device Learned all existing IP addresses and request to turn Wifi ON.

  3. :graduation_cap: Learn mode : Learned in progress, got 3 Wifi networks

  4. Learn Phone OFF , Wifi OFF, :person_walking: Not present is shown after defined time

  5. :house: Present : Wifi is ON , Presence sensor showing Present

Happened to be catching up in the forum right as you posted this; I’m intrigued and will try to make time to play with this over the weekend. I’m not a network pro so maybe this is no big deal; the constant pinging from the hub seems like it might create a lot of extra load on the hub or network traffic. I guess there’s no data being transmitted so it’s not like it’s going to bog down wifi but it seems potentially excessive. Would it be possible to add a setting for the ping interval on each device?

Is it possible to manually enter an IP instead of learning them? For instance, for a regular but infrequent visitor who has no reason to have ST installed on their phone, I’d like to be able to assign a fixed IP on my router to their device and create a presence device for them. The learning technique is handy for someone who isn’t able to obtain that info on their own but manual entry would make this a more powerful tool.

Thanks @MarkTr, glad you’ll give it a try! :slightly_smiling_face:

Both are already in there:

:stopwatch: Check interval (per device):
Device → Settings → Check every (seconds), from 15 to 300 (default 30). Each presence device has its own value.

On load: it isn’t really a ping flood. Each check is one tiny TCP connection attempt to the phone’s IP, a few dozen bytes. When the phone is home it answers on the first try. When it’s away, the router usually reports “no route to host” almost immediately and the check stops there. So at 30 seconds it’s a handful of small packets per minute per phone, which the hub and network won’t notice. If you’d still rather go lighter, 60–120 seconds works fine. Arrival detection just gets a bit slower.

:writing_hand: Manual IP (no Learn needed):
Device → Settings → Phone IP (optional): just type the IP, e.g. 192.168.1.50. You can also enter several, comma-separated (e.g. 192.168.1.50, 192.168.1.51), if the device gets different addresses on different SSIDs.

That’s exactly the visitor case: reserve an IP for their phone on your router, create a device (Add another phone), and enter that IP. Nothing needs to be installed on their phone. Learn is just a convenience for people who don’t know their IP.

One tip: their phone should use its real MAC address on your network (iPhone: Private Wi-Fi Address → Off; Android: Use device/phone MAC). Otherwise the router reservation won’t match it.

Let me know how it goes! :+1:

Coffee coming your way for a nice bit of work!

Of course, my iPhone has always supported detecting my home Wi-Fi, but Apple’s security restrictions require confirmation every time the action is triggered, if the phone is unlocked of course, making it useless for automations.

For a couple of years, I used BLE with a Tile tag, but now, like other iBeacon tracker manufacturers, they randomise the MAC address to prevent stalking. Probably a good thing, but it’s broken my setup, so I was interested to try this project.

It’s working great when leaving home, but I’ve noticed that shortly after reconnecting on arrival, it sometimes retriggers the Away routine.

The “Away after (minutes offline)” setting is a nice touch, but even after increasing it to 5 minutes, I still see repeated Not Present – Present events in the history.

Any thoughts on this?

P.S. I’m pinging the iPhone every 30 seconds using its reserved IP.

Thanks a lot for the coffee, @Johnnybegoode :hot_beverage::folded_hands:

What you’re seeing is almost certainly the iPhone’s power saving. Once the phone is locked and idle, iOS puts the WiFi radio to sleep and the phone can stop answering on the network for several minutes. With Away after = 5 minutes, one long nap is enough to trigger a false “Not present”, and the next check that reaches the phone flips it back to “Present”. That’s the Not present → Present pair you see in History.

:hammer_and_wrench: New version is out (2026-10-14T20:01):
:white_check_mark: Waits longer for a sleeping phone to answer each check
:white_check_mark: Before declaring “away”, it retries for about 30 more seconds. If the phone answers, it stays Present.

It reaches your hub automatically from the channel within about 12 hours. To get it right away, open the channel invite link → Available Drivers → reinstall WiFi Presence SD.

Also recommended for iPhones:
:stopwatch: Raise Away after to 10–15 minutes. Arrival stays instant (~30 s), only “away” is reported a bit later.
:repeat_button: Keep Check every at 30 seconds.
:locked: Make sure Private Wi-Fi Address is Off for your home network (Settings → Wi-Fi → ⓘ) so your router reservation matches.

:clipboard: If it still happens, a log would really help:

  1. Install the SmartThings CLI: Releases · SmartThingsCommunity/smartthings-cli · GitHub
  2. Run:
   smartthings edge:drivers:logcat d65aaeb1-203f-42a8-927f-9ea07acd551a

(it asks you to log in and pick your hub the first time)
3. Leave it running, come home, lock the phone, and wait for a false Not present.
4. Paste the lines from about 10 minutes before it (from no answer ... to -> not present).

Thanks again for the support and feedback! :+1:

Real improvement with this update.:+1:
Maintaining 30 second pinging and Away at 5 minutes it now seems to be working for me.
Just to illustrate from the device history showing Present - Not Present from last week compared to 24 hours


This is aimed squarely at my biggest headache: arrival. My arrival automations are the least reliable part of my SmartThings setup — GPS sometimes notices me a minute after I’m already through the front door, which rather defeats the point of an arrival routine that unlocks the door and lights the entry. WiFi presence with ~30-second detection, running locally on the hub, sounds like the fix.

My setup plan, borrowing from my day job in IT support: set the phone to use its fixed MAC on my home network, reserve a fixed IP for it in the router, then run Learn. One question on that: my WiFi is a mesh — 2.4 and 5 GHz under one SSID, plus an extender. If the phone always lands on the same reserved IP no matter which band or access point it joins, is a single Learn enough? Or do you still recommend learning on each band the way the instructions describe, in case the phone shows up from a different address when it roams?

Second question, on the away side: I read the discussion above about sleeping iPhones, false ‘not present’ results, and the new retry behaviour before declaring away. For Android phones, are people seeing the same deep-sleep WiFi drops, or does Android stay reachable enough that shorter Away-after values are safe? I want presence to feed my lock and arming routines, and a false ‘everyone has left’ at 3 a.m. is exactly what I’m trying to avoid.

Thanks for building this — local execution and no extra app on the phone is precisely how I like to run things.

Besides the sleep issues you’ve mentioned, the effectiveness of Wi-Fi presence is directly dependent on how strong your Wi-Fi signal is and when you want arrival actions to occur. As I mentioned in the other topic, I want my door to unlock prior to stepping on the front porch. I’m not sure that my phone will be guaranteed to have join my Wi-Fi network prior to that happening.

Thanks @DanielBrooks , great questions, and your plan is exactly the setup I recommend :+1:

:antenna_bars: Mesh / single SSID: is one Learn enough?
Yes. If the phone always gets the same reserved IP, whatever band or access point it joins, one Learn is all you need. You can even skip Learn entirely: type the reserved IP into Phone IP in the device settings.

Learning on each network is only for setups where the phone gets different IPs, e.g. a second router or extender running its own DHCP. A quick check: look at the phone’s IP while it’s on 2.4 GHz, on 5 GHz and near the extender. Same IP everywhere means you’re done.

One mesh/extender gotcha: some extenders in repeater mode show their clients to the main router under the extender’s own MAC. If your router’s DHCP client list shows your phone’s real MAC, the reservation will work fine.

:battery: Android vs iPhone on the away side
In my testing, Android phones (Samsung) stay reachable much more consistently than iPhones, but they aren’t immune: Doze can still delay answers now and then. For security routines I wouldn’t go below 10 minutes on either platform. The cost is only a later “away”; arrival stays fast.

Before declaring “Not present”, the driver also retries for about 30 extra seconds after the away delay, so a single missed answer won’t flip it.

:locked_with_key: For lock and arming routines, a few suggestions:

  • Arming: use “all members Not present” and keep Away after at 10+ minutes. Adding a condition like “front door opened in the last 15 minutes” makes a 3 a.m. false “everyone left” practically impossible.
  • Arrival: detection is ~30 s after the phone joins your WiFi. Phones usually reconnect as you approach, but some only rejoin once you wake the screen. Test from the curb a few times before relying on it for unlocking.
  • Since presence comes from the phone’s WiFi connection, anyone holding your phone near the house counts as you. Worth keeping in mind for auto-unlock :slightly_smiling_face:

Enjoy, and let me know how it works on your mesh!

You also need to be aware that there are reported issues with Wi-Fi 7 meshes and Android fused location causing false location changes. Here is a write-up on it:

Android’s Fused Location Provider combines GPS, Wi-Fi positioning, cellular data, and motion sensors to estimate a device’s location. With Wi-Fi 7 mesh networks, multiple access points, band steering, and client roaming can change the Wi-Fi signals and BSSIDs visible to Android, even when the phone is stationary. Since Wi-Fi positioning relies partly on Google’s database of known access points, newly installed or replaced mesh equipment may introduce BSSIDs whose physical locations are not yet accurately represented. These factors can potentially contribute to transient location inaccuracies, particularly indoors where GPS reception may be limited.

For applications using geofencing, these temporary inaccuracies could result in false departure and arrival events without any actual movement. Different applications may respond differently to the same location information depending on how they handle accuracy, filtering, and geofence hysteresis. For example, one application might immediately trigger a departure followed by an arrival, while another maintains a stable presence state. This isn’t necessarily a Wi-Fi 7 defect, but rather a potential interaction between mesh networking, Android’s fused location services, and application-specific geofence processing.

Thanks @h0ckeysk8er, good write-up, and a useful point for anyone relying on geofencing :+1:

It’s actually one of the reasons I built this driver: WiFi Presence SD doesn’t use location at all. No GPS, no Fused Location Provider, no geofence. The hub simply checks, over the local network, whether the phone’s IP answers. So BSSID changes, band steering or Google’s AP database can’t move your “location” or trigger a false departure.

What can affect it on a mesh:
:antenna_bars: Roaming between nodes or bands causes a short disconnect of a second or two. The Away after delay (10 min recommended) plus the retry burst before “Not present” absorbs that.
:locked: IP consistency: as long as one DHCP server hands out the addresses, ideally with a reservation, the phone keeps the same IP on every node and band, so one Learn (or one manually entered IP) is enough.

So if you’ve seen false arrivals and departures with the SmartThings app’s geofence on a Wi-Fi 7 mesh, this may be a good way around it :slightly_smiling_face:

I tried your driver out and so far it seems to be working well.

Not working properly on my phone. I set it up and it learned two IPs. I set up two Routines, one to notify when present and one to notify when not present. Two hours after setting it up, my "Is present’ Routine activated immediately followed by my “Not present” Routine even though the phone never went anywhere. The history shows a Not present event immediately followed by a Present event. At the moment, the sensor shows Present even though I’m not even connected to my home Wi-Fi.

Thanks for testing and reporting, @h0ckeysk8er :folded_hands:

“Present” while you’re off your Wi-Fi almost always means one of the two learned IPs isn’t your phone. If another device joined the network during Learn (a laptop, TV or another phone), the driver may have learned its IP, and that device keeps answering while you’re away. I hit exactly this during testing.

Quick fix:

  1. On your phone, while on your home Wi-Fi, check its IP: Wi-Fi → ⓘ / :gear: → IP address.
  2. In the device: Settings → Phone IP → enter only that IP.
  3. Clear learned IPs → turn it On, then Off. Learned IPs should now show only your phone’s IP.
  4. Ideally, reserve that IP for your phone in the router, and make sure the phone uses its real MAC (not Private / Randomized) on your home network.

The Not present → Present pair: what’s your Away after set to? Phones can stop answering for several minutes while asleep. Below 10 minutes, a long nap can trigger a false “away”. I recommend 10 minutes or more.

If it still misbehaves after that, a log would help a lot:

smartthings edge:drivers:logcat d65aaeb1-203f-42a8-927f-9ea07acd551a

The lines around the event (no answer [...], -> not present, -> present) show which IP answered and when.

Also, which phone is it (Android or iPhone, and model)? :slightly_smiling_face:

Ok, new round of testing. Android 16 on a Galaxy S24 Ultra

Pinned DHCP address to Wi-Fi hardware MAC. Add the fixed IP address to the settings. Run the learn process and it learns one additional IP for some reason. Disconnect from my home Wi-Fi by turning it off on the phone. Sensor never says I’m not present. Should it?

Driver log

✔ connected
2026-10-26T14:53:43.405514901-07:00 TRACE WiFi Presence SD  Received event with handler capability
2026-10-26T14:53:43.411651573-07:00 INFO WiFi Presence SD  <Device: 7ff15a79-2721-4a99-9c67-3523209b468d (Bruce's Wi-Fi Presence)> received command: {"args":{},"capability":"refresh","command":"refresh","component":"main","named_args":{},"positional_args":{}}
2026-10-26T14:53:43.417012546-07:00 TRACE WiFi Presence SD  Found CapabilityCommandDispatcher handler in wifi-presence-sd
2026-10-26T14:53:43.420777392-07:00 INFO WiFi Presence SD  Bruce's Wi-Fi Presence: emit learnedIps = 192.168.1.x: 233, 204
2026-10-26T14:53:43.424146558-07:00 INFO WiFi Presence SD  <Device: 7ff15a79-2721-4a99-9c67-3523209b468d (Bruce's Wi-Fi Presence)> emitting event: {"attribute_id":"ips","capability_id":"perfectworld33337.learnedIps","component_id":"learn","state":{"value":"192.168.1.x: 233, 204"}}
2026-10-26T14:53:43.501443026-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:53:54.989381452-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:54:24.746423220-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:54:55.760656898-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:55:24.724278930-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:55:54.660370426-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:56:24.689395922-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:56:54.692666834-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:57:24.650509373-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:58:07.106173687-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:58:27.887861188-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:58:57.926144952-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:59:28.115335396-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T14:59:58.026348374-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:00:27.928848314-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:00:57.956640960-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:01:28.107431377-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:01:57.804603096-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:02:27.921270112-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:02:57.937299443-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:03:27.959717202-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:03:57.953736596-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:04:27.857729678-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:04:58.062671352-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:05:27.941048896-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:05:57.926667022-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:06:27.925347853-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:06:57.930786240-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled
2026-10-26T15:07:28.044961713-07:00 DEBUG WiFi Presence SD  WiFi Presence 1 device thread event handled