diff --git a/docs/user/site.rst b/docs/user/site.rst
index 88859a29990538e90e2eb00221fa360e595e29d6..b1549b23b999941d2000e76c05134227e62dd8f0 100644
--- a/docs/user/site.rst
+++ b/docs/user/site.rst
@@ -172,6 +172,10 @@ wifi5 \: optional
     When set this offers the outdoor mode flag for 5 GHz radios in the config mode which
     reconfigures the AP to select its channel from outdoor chanlist, while respecting
     regulatory specifications, and  disables mesh on that radio.
+    The ``outdoors`` option in turn allows to configure when outdoor mode will be enabled.
+    When set to ``true`` all 5 GHz radios will use outdoor channels, while on ``false``
+    the outdoor mode will be completely disabled. The default setting is ``'preset'``,
+    which will enable outdoor mode automatically on outdoor-capable devices.
     ::
 
       wifi5 = {
diff --git a/package/gluon-core/check_site.lua b/package/gluon-core/check_site.lua
index b14825083bea117337b6e7cbb658636af0ef0bd0..74a6c3f9a3252ec19b569555babf9f60f8e6019f 100644
--- a/package/gluon-core/check_site.lua
+++ b/package/gluon-core/check_site.lua
@@ -44,6 +44,7 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do
 				149, 151, 153, 155, 157, 159, 161, 165, 169, 173 }
 			need_one_of({config, 'channel'}, channels)
 			need_chanlist({config, 'outdoor_chanlist'}, channels, false)
+			need_one_of({config, 'outdoors'}, {true, false, 'preset'}, false)
 		end
 
 		obsolete({config, 'supported_rates'}, '802.11b rates are disabled by default.')
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/180-outdoors b/package/gluon-core/luasrc/lib/gluon/upgrade/180-outdoors
new file mode 100755
index 0000000000000000000000000000000000000000..3acaa63c93d973202193eb40229fd82e70deec5e
--- /dev/null
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/180-outdoors
@@ -0,0 +1,35 @@
+#!/usr/bin/lua
+
+-- This script needs to be sorted before 200-wireless as it affects
+-- wireless channel selection and wireless mesh configuration.
+
+local uci = require('simple-uci').cursor()
+local site = require 'gluon.site'
+
+if uci:get('gluon', 'wireless', 'outdoor') ~= nil then
+	-- don't overwrite existing configuration
+	os.exit(0)
+end
+
+local sysconfig = require 'gluon.sysconfig'
+local platform_info = require 'platform_info'
+
+local config = site.wifi5.outdoor_preset('preset')
+local outdoor = false
+
+if sysconfig.gluon_version then
+	-- don't enable the outdoor mode after an upgrade
+	outdoor = false
+elseif config == 'preset' then
+	-- enable outdoor mode through presets on new installs
+	outdoor = platform_info.is_outdoor_device()
+else
+	-- enable/disable outdoor mode unconditionally on new installs
+	outdoor = config
+end
+
+uci:section('gluon', 'wireless', 'wireless', {
+	outdoor = outdoor
+})
+
+uci:save('gluon')
diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
index 5b4f559a6a25c81cb506073d4c5e97c9bb2d88e1..17d881f620df541d4dec1a7635fd37603a131fcf 100644
--- a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
@@ -27,3 +27,23 @@ function match(target, subtarget, boards)
 
    return true
 end
+
+function is_outdoor_device()
+   if match('ar71xx', 'generic', {
+      'cpe510-520-v1',
+      'ubnt-nano-m',
+      'ubnt-nano-m-xw',
+      }) then
+      return true
+
+   elseif match('ar71xx', 'generic', {'unifiac-lite'}) and
+	   get_model() == 'Ubiquiti UniFi-AC-MESH' then
+      return true
+
+   elseif match('ar71xx', 'generic', {'unifiac-pro'}) and
+	   get_model() == 'Ubiquiti UniFi-AC-MESH-PRO' then
+      return true
+   end
+
+   return false
+end