Back home the data is dumped on my PC,
imported in a MS Access database (to simplify some math) and a HTML file
calling Google Maps is generated.
The router name in red is open. The yellow
one is WEP or WPA_PSK or WPA2_PSK. The white ones are WPA_WPA2_PSK.
The red dots are the sampling points. The markers are the other routers. The red lines show the points that were used to triangulate. The streets names and the MAC address were erased on purpose.
Disclaimer: This is an approximate triangulation and the signal strength depends where is the source inside the home which impact the results. Also, the triangulation I’m doing is kinda wrong. You cannot just use the coordinates as XY like I did because they are on a sphere but for short distance it's OK.
Triangulation
To understand how I did it, see the triangulation as vectors with different signal strengths. Each one "pulling" with its own strength. All of the triangulation computing is done with some queries in the database. This saves A LOT of code.
The RSSI (Received signal strength indication) is an attenuation given in negative dB: 90db is less than 60dB and so on. To simplify things, I work with positive numbers as a kind of “signal strength”:
Strength = (100 + RSSI)
Why 100? Because the RSSI given by the ESP never goes below 99dB. So a 90dB signal give me a strength of 10, 60dB = 40 and so on.
Some simple math now. For a given Access Point (AP) I do a sum of all the measured signal strength: let's call it [RSSI_Sum].
Then for each sample (Strength @ coordinate) I compute a strength ratio (the vector "Strength"):
SignalRatio_@LatLong1 = Strength_@LatLong1 / [RSSI_Sum]
SignalRatio_@LatLong2 = Strength_@LatLong2 / [RSSI_Sum]
...
SignalRatio_@LatLong_n = Strengt_@LatLong_n / [RSSI_Sum]
Here is some partial results:
Then I triangulate (ok, approximate a triangulation) the lat/long by doing a sum of... I don't know how to explain it in English...
For each GPS coordinate I do apply the SignalRatio of that coordinate then sum them all:
Latitude = Sum( Lat_n * [SignalRatio_n] )
Longitude = Sum( Long_n * [SignalRatio_n] )
Kind look like this in SQL:
SELECT SSID, Sum(Lat*[SignalRatio]) AS Lat, Sum(Lng*[SignalRatio]) AS Lng
FROM …
GROUP BY SSID
It's a really rough triangulation because the coordinates are on a sphere (our planet) but I think it's OK for a few meters.
Finally, a dotNET app is used to build a HTML file with some generated JavaScript for the Google Maps API. It’s ugly but for a onetime project that’s OK.
There you are MutherF***er…
I was so stunned by the simplicity of your solultion, that it made me think quite alot more. And I came to the conclusion that perhaps you should not immediately start calling that neighbour the m**f**ker:)
Your calculation is very simple, but even in flatspace a very rough approximation. You sort of weightedaverage the position based on the gps coordinates and wifi strengths. Although this is somewhat intuitively in the right direction, it is definitely only an approximation.
For starters, it assumes the signal fades linearly over distance, and secondly ignores the fact that the source should be radiating out from a single point in space.
Especially that last bit should mean that any result is only an estimate, and it is possible to come up with a "certainty" of a result, and see if adding more measurements makes it converge or not. (In your case it will always give "an" output, but possibly a very wrong one)
Regarding the first problem: even in free space the signalpower drops with the distance^2, and due to obsticales, results may be widely inacurrate. (you might be very close and get a bad signal, and vice versa).
A toy examples where both approaches differ greatly:
 Assume you walked 20 meters west of the target, in a line from south to north
^

 (*)


In your calculation the target would be exactly on that line. (which it obviously isn't). A more proper calculation could look at the signal power more carefully, and would find that the signals match better a situation of a source not on the line. (For the simple reason that following the line does not drop the signal level as much as it would if the source was on it)
But aside from the fact that the result might not be so accurate, all the rest in the post remains pretty neat, and I'm pretty sure you never assumed it to be super accurate in the first place. So please don't take this as any criticism, but rather as a funny thought that you made someone think a lot about something that was not the point:)