davidchatting / Approximate

The Approximate Library is a WiFi Arduino library for building proximate interactions between your Internet of Things and the ESP8266 or ESP32
MIT License
124 stars 17 forks source link

Unnecessary departs? #18

Closed SensorsIot closed 3 years ago

SensorsIot commented 3 years ago

I used the closeby example and extended it a little to switch a Sonoff relay on and off: approx.setProximateDeviceHandler(onProximateDevice, APPROXIMATE_PERSONAL_RSSI, 5000);

and

switch (event) { case Approximate::ARRIVE: Serial.println("ARRIVE\t" + device->getMacAddressAsString()); if (device->getMacAddressAsString() == macaddress) { digitalWrite(LED_PIN, HIGH); Serial.println("ARRIVE\t" + device->getMacAddressAsString()); } break; case Approximate::DEPART: Serial.println("DEPART\t" + device->getMacAddressAsString()); if (device->getMacAddressAsString() == macaddress) { digitalWrite(LED_PIN, LOW); Serial.println("DEPART\t" + device->getMacAddressAsString()); } break; }

Even if the Smartphone is very close to the Sonoff, it creates a lot of departure messages. I set the timer to 5000 to get a fast reaction for a demonstration. It would be good if we would get RSSI values in Serial for debugging...

davidchatting commented 3 years ago

Hi - you can get RSSI from the device like this: device->getRSSI()

I though that perhaps you were getting DEPART messages for devices that aren't the Sonoff - but now I see you're checking for the mac address - so that's not the problem

SensorsIot commented 3 years ago

This is the output: Approximate::begin Approximate::connectWiFi private-2G Approximate::begin DONE WL_DISCONNECTED WL_CONNECTED PacketSniffer::begin WL_IDLE_STATUS ARRIVE 4A:CD:D5:A3:D4:AE -37 ARRIVE 4A:CD:D5:A3:D4:AE DEPART 4A:CD:D5:A3:D4:AE -39 DEPART 4A:CD:D5:A3:D4:AE ARRIVE 4A:CD:D5:A3:D4:AE -39 ARRIVE 4A:CD:D5:A3:D4:AE DEPART 4A:CD:D5:A3:D4:AE -39 DEPART 4A:CD:D5:A3:D4:AE ARRIVE 4A:CD:D5:A3:D4:AE -34 ARRIVE 4A:CD:D5:A3:D4:AE DEPART 4A:CD:D5:A3:D4:AE -34 DEPART 4A:CD:D5:A3:D4:AE

The limit is 40

davidchatting commented 3 years ago

That's odd and that's happening more frequently than the 5000ms interval you've set?

You're using APPROXIMATE_PERSONAL_RSSI which is defined as -40 and your RSSI are very close to that value - perhaps try chaning it to APPROXIMATE_SOCIAL_RSSI (-60) or you can set is manually?

SensorsIot commented 3 years ago

no. Every 5 seconds or a multiple of it. But it should not happen.

davidchatting commented 3 years ago

It will happen if it doesn't see any packets from the device within that interval.

Are you trying have it be very responsive when your device moves away? If not just increase the interval, but if you are then I probably need to revisit the code because I don't think it will trigger the DEPART when it sees a reading under the RSSI thresoild value at the moment.

SensorsIot commented 3 years ago

The iPhone lays about 20 cm apart from the ESP. Nothing moves as you see in RSSI

davidchatting commented 3 years ago

Try increasing the interval to probably something like 15 secs - it's not a sampling interval, it's a timeout - so very dependant on whether the phone is active on the network or not

SensorsIot commented 3 years ago

This is not the issue. It only would cover the fundamental problem. Why is a departure detected with an RSSI of -38 if the threshold i -40? Did you implement a hysteresis?

davidchatting commented 3 years ago

No, I think it might be the solution. The RSSI value displayed for the DEPART is the last good value it saw - because DEPART is triggered by an absense of readings (after the timeout) not a new one - so that does make sense - although is certainly confusing!

SensorsIot commented 3 years ago

I understand. I would use two different time constants. One for a lower RSSI which means, the phone moved and a second one, that the device disappeared. Otherwise, these distances only make sense for the approach and not for the departure. I would expect that, if RSSI is substantially below the threshold (hysteresis), the light switches off. And if the address is no more discovered after the typical interval ( much longer) the light also has to go off, of course.

davidchatting commented 3 years ago

Yes, very good points. I will see if I can put this into the code.

In the meantime for your application I wonder if you'd be better using the Watch Device example - bring the device close grab the mac address, then use the onActiveDevice handler to get the real-time RSSI value and add your logic on top of that.

SensorsIot commented 3 years ago

I stay with it for my video. I am sure you will find an appropriate solution.

davidchatting commented 3 years ago

I will spend some time on this tomorrow - I don't think it'll take long to get something that works nicely

davidchatting commented 3 years ago

Hi - I think I have a working solution on the development branch now - would you be able to take a look?

I think it's best to keep the default timeout when using setProximateDeviceHandler()

Thanks! :)

SensorsIot commented 3 years ago

It still departs with a high RSSI:

ARRIVE 4A:CD:D5:A3:D4:AE -25 Millis: 19815 DEPART 4A:CD:D5:A3:D4:AE -36 Millis: 21837 ARRIVE 4A:CD:D5:A3:D4:AE -26 Millis: 21899 DEPART 4A:CD:D5:A3:D4:AE -24 Millis: 39069 ARRIVE 4A:CD:D5:A3:D4:AE -24 Millis: 49306

I think you have to find out with which interval the iPhone transmits a signal. If the time is shorter than this time, you cannot decide on a departure because you do not know if it is departed or just saving energy. Only if you get a lower RSSI or the time from the last signal is long enough you can decide that it departed. My sketch had an array of all MAC addresses in range to keep track. I think you also have to extend your library in this direction. Also because people probably want to have two or more Mac addresses tracked (also an array).

davidchatting commented 3 years ago

Yes, a high RSSI value is a good indication of proximity, but low values might not always reflect increased distance as they can be attenuated by a moving body or as you suggest a low power mode. As such the library was designed to use peak RSSI values and determine a departure when no high value (higher than the threshold) has been seen after a timeout. This interval needs to be set to reconcile the desired responsiveness of the application and the frequency of network packets sent by the device (for received traffic the RSSI is relative to the router and so is not helpful) and that will be a compromise. So, for now, I have reverted to the simple threshold crossing for arrival and timeout for departure. However, I absolutely welcome pull-requests with better solutions.

The library does manage tracking multiple devices – the Approximate class maintains a list of Devices (proximateDeviceList). If you want to look for specific devices you do that with one of the setActiveDeviceFilter() methods in combination with an Active Device Handler – the Proximate Device Handler don’t currently use these filters. If you can share your code, perhaps I can see a neater way to solve your problem or extend the library to make it so?

For a departure event printing the RSSI value will show the cached “last good” value it saw - so that's why you RSSI values are high. I suggest you use the FindMy example with the Active Device Handler if you want a real-time stream of RSSI values.

SensorsIot commented 3 years ago

Ok with me. It is your decision. Maybe after the video tomorrow you will get additional feedback.

davidchatting commented 3 years ago

Very interesting video (https://www.youtube.com/watch?v=cXh0T1CWtyg) - thank you!

I think I understand a little better how you are using the library now and I think we are talking about two different architectures for the Sonoff example. In mine the IoT devices are largely unchanged and the ESP is the mobile element that discovers and sends HTTP requests with these devices - in yours the ESP codes runs on the IoT device itself and using mobile devices (like phones) as access tokens (via their MAC address) - and as you point out that's vulnerable to spoofing. And that's why you need to store a list of MAC addresses on device.