Since Edison does not have a sensor, it is not possible to pick up information from the outside world without attaching various sensors externally. ・ ・ Can't you pick it up?
** You can get Wifi information! !! ** **
Geolocation is the estimation of the position on the map. GPS is famous. GPS is a technology that estimates the position by the general theory of relativity based on the time information sent from geostationary satellites that are orbiting far around the earth. But this time it doesn't matter. The target this time is information on Wifi access points (APs) scattered around the world. Many APs continue to emit radio waves at one point without being moved too much. Since the radio waves used in Wifi etc. have high frequencies, they are quickly attenuated and do not fly too far. In addition, it is known that the strength of radio waves attenuates with distance. Looking at the nature of this area, some people thought that the position of the received device on the map could be specified by the strength of the Wifi signal. And Google has done that on a global scale. And how, we can also use the API. That is Google Map Geolocation API. If you send the surrounding AP information consolidated in JSON to the API URL, the estimated position information will be returned immediately.
Please register as a developer with Google and obtain the API key of Google Map. This is the GAPI_KEY in the code below. It seems that it can be used free of charge within 1000 requests / day and 1 request / second. Of the following code. Where it is ELI_MAC, enter the MAC address of the AP to be excluded from the position estimation. In my case, I put the MAC address of the tethering mobile phone used for Edison's communication.
geo.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import commands, datetime, time
import re
import json, requests
GAPI_KEY = "fa1iuEe32hw4iusiWKgrwFEheERfieunGeWW"
ELI_MAC = ["12:34:56:78:9A:BC"]
re_mac = re.compile("\s+Cell \d{2} - Address: (\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})")
re_ch = re.compile("\s+Channel:(\d+)")
re_freq = re.compile("\s+Frequency:(\S+) GHz")
re_qual = re.compile("\s+Quality=(\S+) Signal level=(\S+) dBm")
re_essid = re.compile("\s+ESSID:\"([^\"]+)\"")
class AP:
def __init__(self, _mac, _channel, _frequency, _quality, _signal, _essid=""):
self.mac = _mac
self.channel = _channel
self.frequency = _frequency
self.quality = _quality
self.signal = _signal
self.essid = _essid
self.time = datetime.datetime.now()
def show(self):
print("%s, %s, %s, %s, %s, %s" % (self.essid, self.mac, self.channel, self.frequency, self.quality, self.signal))
def getVal(self):
t = datetime.datetime.now() - self.time
age = t.seconds * 1000 + t.microseconds / 1000
return {"macAddress":self.mac, "signalStrength":self.signal, "age":age, "channel":self.channel}
def getAPList():
aplist = []
res = commands.getoutput("/sbin/iwlist wlan0 scan")
essid = ""
mac = ""
channel = ""
frequency = ""
quality = ""
signal = ""
for t in res.splitlines():
m = re_mac.match(t)
if m:
mac = m.group(1)
continue
m = re_ch.match(t)
if m:
channel = m.group(1)
continue
m = re_freq.match(t)
if m:
frequency = m.group(1)
continue
m = re_qual.match(t)
if m:
quality = m.group(1)
signal = m.group(2)
if mac not in ELI_MAC:
aplist.append(AP(mac, channel, frequency, quality, signal, essid))
continue
m = re_essid.match(t)
if m:
essid = m.group(1)
continue
return aplist
def getLocationFromWifi(wifilist):
url = "https://www.googleapis.com/geolocation/v1/geolocate?key=%s" % GAPI_KEY
headers = {"Content-Type": "application/json"}
data = json.dumps({"wifiAccessPoints":wifilist})
r = requests.post(url, data=data, headers=headers)
geo = r.json()
return {"Latitude":geo['location']['lat'], "Longitude":geo['location']['lng'], "Accuracy":geo['accuracy']}
if __name__ == '__main__':
aps = {}
while True:
naps = getAPList()
lapsk = aps.keys()
napsk = []
# add new APs to AP list.
for ap in naps:
if ap.mac not in lapsk:
aps[ap.mac] = ap
# make new AP names list
napsk.append(ap.mac)
# search missed APs to delete from AP list
for ap in lapsk:
if ap not in napsk:
aps.pop(ap)
loc = getLocationFromWifi([d.getVal() for d in aps.values()])
print("Latitude: %f, Longitude: %f, Accuracy; %f" % (loc['Latitude'], loc['Longitude'], loc['Accuracy']))
print("https://www.google.co.jp/maps/@%s,%s,21z?hl=ja" % (loc["Latitude"], loc["Longitude"]))
time.sleep(30)
Execute this code with administrator privileges. When I ran it at home with the intention of testing it, I was a little scared because it was identified at a level that I might even know the room number.
The results of position estimation when moving between Akihabara and Ochanomizu on foot are shown below. The red dot is the estimated position. In this experiment, in order to avoid the time limit of the API, only the AP information was acquired, and the position estimation was performed after returning home.
The GPS data when walking while collecting Wifi information around the area with Edison is as follows. Again, the accuracy is not so good, so it is for reference only.
I laugh at the place where the red dot suddenly appears in front of Ochanomizu station, but there are also places where I am surprised to estimate the position. If you filter at a common sense movement speed, or?
Yeah. I chose Akihabara as the experimental site because I thought there would be a large number of sample Wifi APs. Depending on the location, I could see nearly 60 APs, which was more than I expected.