diff --git a/hoodselector/Makefile b/hoodselector/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f7c2efc9a7068eb333f5750548c659b84d2af7d9
--- /dev/null
+++ b/hoodselector/Makefile
@@ -0,0 +1,36 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ffnw-hoodselector
+PKG_VERSION:=1
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/$(PKG_NAME)
+  SECTION:=networke
+  CATEGORY:=Freifunk Nordwest
+  TITLE:=Select the hoods depending on the geo coordinate
+  DEPENDS:=+lwtrace +libwlocate +ffnw-hoods
+endef
+
+define Package/$(PKG_NAME)/description
+	Select the hoods depending on the geo coordinates
+endef
+
+define Build/Prepare
+	mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/$(PKG_NAME)/install
+	$(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,$(PKG_NAME)))
diff --git a/hoodselector/files/usr/lib/micron.d/hoodselector b/hoodselector/files/usr/lib/micron.d/hoodselector
new file mode 100644
index 0000000000000000000000000000000000000000..c2e6f98c1649758cb0dd9e0f226ea0ca6ba48a70
--- /dev/null
+++ b/hoodselector/files/usr/lib/micron.d/hoodselector
@@ -0,0 +1 @@
+* * * * * /usr/sbin/hoodselector
diff --git a/hoodselector/files/usr/sbin/hoodselector b/hoodselector/files/usr/sbin/hoodselector
new file mode 100755
index 0000000000000000000000000000000000000000..e1c8c1e0daa693594d5b2596f68ba35adaededa0
--- /dev/null
+++ b/hoodselector/files/usr/sbin/hoodselector
@@ -0,0 +1,461 @@
+#!/usr/bin/lua
+
+local pidPath="/var/run/hoodselector.pid"
+
+if io.open(pidPath, "r") ~=nil then
+	io.stderr:write("The hoodselector is still running.\n")
+	os.exit(1)
+else
+	io.close(io.open(pidPath, "w"))
+end
+
+function pid_clean()
+	if io.open(pidPath, "r") ~=nil then
+		os.remove(pidPath)
+	end
+end
+
+local json = require ("dkjson")
+local file = '/lib/ffnw/hoods/hoods.json'
+local uci = require('luci.model.uci').cursor()
+
+-- Read the full hoodfile. Return nil for wrong format or no such file
+local function readhoodfile(file)
+	local obj, pos, err = json.decode (io.popen(string.format("cat %s",file), 'r'):read('*a'), 1, nil)
+	if err then
+		return nil
+	else
+		return obj
+	end
+end
+
+-- Return a wifi device list
+local function get_wifi_devices()
+        local radios = {}
+        uci:foreach('wireless', 'wifi-device',
+                function(s)
+                        table.insert(radios, s['.name'])
+                end
+        )
+        return radios
+end
+
+-- Get Geoposition if no static position present try strace. Return nil for no position
+local function get_geolocation()
+	local lat = uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'latitude')
+	local lng = uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'longitude')
+	if ( lat == nil or lng == nil ) then
+		for scan in io.popen(string.format("lwtrace -t 2> /dev/null"), 'r'):lines() do
+			if string.find(scan,"(lat)") then
+				local last_val = nil
+				for geo in string.gmatch(scan,"[^%s]+") do
+					if geo == '(lat)' then
+						lat = last_val
+					end
+					if geo == '(lon)' then
+						lng = last_val
+					end
+					last_val = geo
+				end
+			end
+		end
+	end
+	local ret = {}
+	table.insert(ret, tonumber(lat))
+	table.insert(ret, tonumber(lng))
+	return ret
+end
+
+-- Return a hood if no default hood has ben defind or the hoodfile dont have any hoods return nil
+local function gethood_by_geo(jhood,geo)
+	local selected_hood = nil
+	local default_hood = nil
+	for n, h in pairs(jhood) do
+		if h.defaulthood then
+			default_hood = h
+		end
+		local in_hood = false;
+		for n, box in pairs(h.boxes) do
+			if ( geo[1] >= box[1][1] and geo[1] < box[2][1] and geo[2] >= box[1][2] and geo[2] < box[2][2] ) then
+				in_hood = true
+				break
+			end
+		end
+		if in_hood then
+			selected_hood = h
+		end
+	end
+	if ( selected_hood == nil ) then
+		selected_hood = default_hood
+	end
+	return selected_hood
+end
+
+local function gethood_by_bssid(jhood, scan_bssid)
+	local selected_hood = nil
+	local default_hood = nil
+	for n, h in pairs(jhood) do
+		if h.defaulthood then
+			default_hood = h
+		end
+		if scan_bssid:match(h.bssid) then
+			selected_hood = h
+		end
+	end
+	if ( selected_hood == nil ) then
+		selected_hood = default_hood
+	end
+	if selected_hood ~= nil then
+		selected_hood.bssid = scan_bssid
+	end
+	return selected_hood
+end
+
+-- boolean check if batman-adv has gateways
+local function get_gw_range()
+	local gw_connect = false
+	for gw in io.popen(string.format("cat /sys/kernel/debug/batman_adv/bat0/gateways"), 'r'):lines() do
+		if gw:match("Bit") then
+			gw_connect = true
+		end
+	end
+	return gw_connect
+end
+
+--Load bssid history
+function bssid_hist_load( sfile )
+	local bssid_his = {}
+	for line in io.popen(string.format("cat %s 2> /dev/null",sfile),'r'):lines() do
+		if line:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then
+			table.insert(bssid_his,line)
+		end
+	end
+	return bssid_his
+end
+
+--Save bssid history
+function bssid_hist_save( tbl,filename )
+	local file,err = io.open( filename, "wb" )
+	if err then return err end
+	for idx,str in ipairs( tbl ) do
+		file:write(str)
+	end
+	file:close()
+end
+
+-- Return the BSSID from the next freifunk router with the best signal quality and with has a difference to the actual used BSSID
+local function get_neigbour_bssid(radios)
+	local hoodbssid = nil
+	local bssid_leases = bssid_hist_load("/tmp/hoodselector.leases")
+	for index, radio in ipairs(radios) do
+		hoodbssid = uci:get('wireless', 'mesh_' .. radio, 'bssid')
+		local bssid_his = ""
+		if bssid_leases[index] ~= nil then
+			bssid_his = bssid_leases[index]
+		end
+		bssid_his = bssid_his..' '..hoodbssid
+		local lastQuality = 255
+		local tmphoodbssid = nil
+		for wifiscan in io.popen(string.format("iw %s scan | grep \"%s\" -B8", uci:get('wireless', 'mesh_' .. radio, 'ifname'), uci:get('wireless', 'mesh_' .. radio, 'ssid')),'r'):lines() do
+			if wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)") then
+				tmphoodbssid = wifiscan:match("(%w+:%w+:%w+:%w+:%w+:%w+)"):upper()
+			end
+			if wifiscan:match("signal:") then
+				local quallity = wifiscan:split(" ")
+				quallity = quallity[2]:split(".")
+				if quallity[1]:match("-") then
+					quallity = quallity[1]:split("-")
+				end
+				quallity = tonumber(quallity[2]:match("(%d%d)"))
+				if not bssid_his:match(tmphoodbssid) then
+					if ( lastQuality > quallity ) then
+						lastQuality = quallity
+						hoodbssid = tmphoodbssid
+					end
+				end
+			end
+		end
+		if ( lastQuality == 255 ) then
+			bssid_his = bssid_his:split(" ")
+			hoodbssid = bssid_his[2]
+			bssid_his = ""
+		end
+		bssid_leases[index] = bssid_his
+	end
+	bssid_hist_save(bssid_leases,"/tmp/hoodselector.leases")
+	return hoodbssid
+end
+
+-- Retun a table of current peers from /etc/config/fastd
+local function get_current_peers()
+	local config_peername = {}
+	uci:foreach('fastd', 'peer',
+		function(s)
+			if s['.name'] then
+				table.insert(config_peername,s)
+			end
+		end
+	)
+	local config_peers = {}
+	for _,index in pairs(config_peername) do
+		for prafix,peer in pairs(index) do
+			local tmp_peer = {}
+			if prafix:match(".name") then
+				if peer:match("mesh_vpn_backbone_peer_") then
+					local tmpremote = uci:get('fastd', peer, 'remote')
+					tmpremote = tmpremote[1]:split(" ")
+					local remote = {}
+					remote['host'] = tmpremote[1]
+					remote[tmpremote[2]] = tmpremote[3]
+					tmp_peer['key'] = tostring(uci:get('fastd', peer, 'key'))
+					tmp_peer['remote'] = remote
+					config_peers[peer] = tmp_peer
+				end
+			end
+		end
+	end
+	return config_peers
+end
+
+--Remove current peers that is not exist in the current hood. Check the integrity and add new peers
+local function set_hoodconfig(hood,radios)
+	local change = false
+	local uci_error = false
+	local config_peers = get_current_peers()
+	for hoodconf,val in pairs(hood) do
+		if hoodconf:match("servers") then
+			for config_index, config_peer in pairs(config_peers) do
+				local remove = true
+				local hood_server = nil
+				for index0,serverlist in pairs(val) do
+					for index1,server in pairs(serverlist) do
+						if index1:match("host") then
+							local hoodserver = server:split('.')
+							if config_index == 'mesh_vpn_backbone_peer_'..hoodserver[1] then
+								remove = false
+								hood_server = index0
+								if not ( config_peer.key == serverlist['publickey'] ) then
+									local err = uci:set('fastd', config_index, 'key', serverlist['publickey'])
+									if not err then
+										uci_error = true
+									end
+									change = true
+								end
+								server = '\"'..server..'\"'
+								if not ( config_peer.remote.host == server ) then
+									local hood_remote = {}
+									table.insert(hood_remote, server..' port '..config_peer.remote.port)
+									local err uci:set('fastd', config_index, 'remote', hood_remote)
+									if not err then
+										uci_error = true
+									end
+									change = true
+								end
+								if not ( config_peer.remote.port == serverlist['port'] ) then
+									local hood_remote = {}
+									table.insert(hood_remote, config_peer.remote.host..' port '..serverlist['port'])
+									local err uci:set('fastd', config_index, 'remote', hood_remote)
+									if not err then
+										uci_error = true
+									end
+									change = true
+								end
+							end
+						end
+					end
+				end
+				if remove then
+					uci:delete('fastd',config_index)
+					change = true
+				else
+					if hood_server ~= nil then
+						table.remove(val,hood_server)
+					end
+				end
+			end
+		end
+		if hoodconf:match("bssid") then
+			local if_change = false
+			for index, radio in ipairs(radios) do
+				if not ( uci:get('wireless', 'mesh_' .. radio, 'bssid') == val ) then
+					uci:section('wireless', 'wifi-iface', 'mesh_' .. radio,
+						{
+							bssid = val
+						}
+					)
+					if_change = true
+				end
+			end
+			if if_change then
+				uci:save('wireless')
+				uci:commit('wireless')
+				os.execute('wifi')
+			end
+		end
+	end
+	for hoodconf,val in pairs(hood) do
+		if hoodconf:match("servers") then
+			for index0,serverlist in pairs(val) do
+				local group = 'mesh_vpn_backbone'
+				local name = serverlist.host:split('.')
+				name = name[1]
+				local remote = {}
+				table.insert(remote, '\"'..serverlist.host..'\"'..' port '..serverlist.port)
+				uci:section('fastd', 'peer', group .. '_peer_' .. name,
+					{
+						enabled = 1,
+						net = 'mesh_vpn',
+						group = group,
+						key = serverlist.publickey,
+						remote = remote
+					}
+				)
+				change = true
+			end
+		end
+	end
+	if change then
+		uci:save('fastd')
+		uci:commit('fastd')
+		os.execute('/etc/init.d/fastd restart')
+	end
+	if uci_error then
+		return false
+	end
+	return true
+end
+
+-- Return nil for broken file or no such file. Or return a table
+-- readhoodfile()
+-- Return a table that included numeric values or nil for no position
+-- get_geolocation()
+-- Return a hood if no default hood has ben defind or the hoodfile dont have any hoods return nil
+-- gethood_by_geo()
+-- Hole liste an wlan chipsetzen, wenn es keine gibts return leere Liste.
+-- get_wifi_devices()
+-- Set hood conf true for pass and false for faild
+-- set_hoodconfig()
+-- Return a scaned bssid that has the best signal quality and was not used before
+-- get_neigbour_bssid()
+-- Hohle hood zur BSSID wenn keine existirt return defaulthood mit geänderter BSSID gibt es keine default hood return nil
+-- gethood_by_bssid()
+
+--Start
+--Lese die Hooddatei ein
+local jhood = readhoodfile(file)
+-- Prüfe ob hooddatei korrekt eingelesen wurde
+if jhood ~= nil then
+	io.stderr:write('Hat hoodfile mit korrektem json\n')
+	-- Liste an wlan chipsetzen
+	local radios = get_wifi_devices()
+	-- Lese geoposition ein
+	local geo = get_geolocation()
+	if geo[1] ~= nil or geo[2] ~= nil then
+		io.stderr:write('Router hat position\n')
+		-- Hole hood anhand von geokoordinaten
+		local geo_hood = gethood_by_geo(jhood, geo)
+		-- Prüfe hood auf fehler
+		if geo_hood ~= nil then
+			io.stderr:write('Hole hood bei position\n')
+			if get_gw_range() then
+				io.stderr:write('Batman GWs in reichweite\n')
+				local no_error = set_hoodconfig(geo_hood,radios)
+				if no_error then
+					io.stderr:write('setze hood bei position\n')
+					pid_clean()
+					os.exit(0)
+				end
+				io.stderr:write('setze hood bei position Fehler\n')
+				io.stderr:write('Error while setting new hood getting by geoposition.\n')
+				pid_clean()
+				os.exit(0)
+			end
+			io.stderr:write('Batman GWs nicht in reichweite\n')
+			if next(radios) then
+				io.stderr:write('WLAN-Scan nach nachbar freifunk Routern\n')
+				local scan_bssid = get_neigbour_bssid(radios)
+				if scan_bssid ~= nil then
+					local bssid_hood = gethood_by_bssid(jhood, scan_bssid)
+					if bssid_hood ~= nil then
+						io.stderr:write('Hole hood bei bssid\n')
+						local no_error = set_hoodconfig(bssid_hood,radios)
+						if no_error then
+							io.stderr:write('setze hood bei bssid oder Setze Defaulthood mit geänderter BSSID wenn keine passende hood exitiert\n')
+							pid_clean()
+							os.exit(0)
+						end
+						io.stderr:write('setze hood bei bssid Fehler\n')
+						io.stderr:write('Error while setting new hood getting by bssid.\n')
+						pid_clean()
+						os.exit(0)
+					end
+					io.stderr:write('Hole hood bei bssid Fehler\n')
+					local no_error = set_hoodconfig(geo_hood,radios)
+					if no_error then
+						io.stderr:write('setze hood bei position\n')
+						pid_clean()
+						os.exit(0)
+					end
+					io.stderr:write('setze hood bei position Fehler\n')
+					io.stderr:write('Error while setting new hood getting by geoposition.\n')
+					pid_clean()
+					os.exit(0)
+				end
+			end
+			io.stderr:write('WLAN-Scan nach nachbar freifunk Routern Fehler\n')
+			local no_error = set_hoodconfig(geo_hood,radios)
+			if no_error then
+				io.stderr:write('setze hood bei position\n')
+				pid_clean()
+				os.exit(0)
+			end
+			io.stderr:write('setze hood bei position Fehler\n')
+			io.stderr:write('Error while setting new hood getting by geoposition.\n')
+			pid_clean()
+			os.exit(0)
+		end
+		io.stderr:write('Hole hood bei position Fehlerhaft\n')
+		io.stderr:write('no default hood has been defined or the hoodfile dont have any hoods.\n')
+		pid_clean()
+		os.exit(0)
+	end
+	io.stderr:write('Router hat keine position\n')
+	if get_gw_range() then
+		io.stderr:write('Batman GWs in reichweite\n')
+		pid_clean()
+		os.exit(0)
+	end
+	io.stderr:write('Batman GWs nicht in reichweite\n')
+	if next(radios) then
+		io.stderr:write('WLAN-Scan nach nachbar freifunk Routern\n')
+		local scan_bssid = get_neigbour_bssid(radios)
+		if scan_bssid ~= nil then
+			local bssid_hood = gethood_by_bssid(jhood, scan_bssid)
+			if bssid_hood ~= nil then
+				io.stderr:write('Hole hood bei bssid\n')
+				local no_error = set_hoodconfig(bssid_hood,radios)
+				if no_error then
+					io.stderr:write('setze hood bei bssid\n')
+					pid_clean()
+					os.exit(0)
+				end
+				io.stderr:write('setze hood bei bssid Fehler\n')
+				io.stderr:write('Error while setting new hood getting by bssid.\n')
+				pid_clean()
+				os.exit(0)
+			end
+			io.stderr:write('Hole hood bei bssid Fehler\n')
+			io.stderr:write('no default hood has been defined or the hoodfile dont have any hoods.\n')
+			pid_clean()
+			os.exit(0)
+		end
+	end
+	io.stderr:write('WLAN-Scan nach nachbar freifunk Routern Fehler\n')
+	pid_clean()
+	os.exit(0)
+end
+io.stderr:write('Lese Hoodfile Fehler\n')
+-- Fehler beim einlesen der Hooddatei
+io.stderr:write('There seems to have gone something wrong while reading hoodfile from ' .. file .. '\n')
+pid_clean()
+os.exit(0)