diff --git a/ALGORITHMS.md b/ALGORITHMS.md index 4153de7..2b9a9df 100644 --- a/ALGORITHMS.md +++ b/ALGORITHMS.md @@ -11,6 +11,8 @@ selected channel. This is only for testing and re-initialization. Parameters: * `mode`: "random" +* `setDifferentChannelPerAp`: If true, will set a different random channel per AP. If false, it will set the same random channel for all APs. + * values: `true`, `false` (default: `false`) ### `LeastUsedChannelOptimizer` This algorithm assigns the channel of the OWF APs based on the following logic: @@ -59,6 +61,8 @@ the value. This is only for testing and re-initialization. Parameters: * `mode`: "random" +* `setDifferentTxPowerPerAp`: If true, will set a different random tx power per AP. If false, it will set the same random tx power for all APs. + * values: `true`, `false` (default: `false`) ### `MeasurementBasedApClientTPC` This algorithm tries to assign the Tx power of the OWF APs based on the @@ -72,6 +76,8 @@ each AP): Parameters: * `mode`: "measure_ap_client" +* `targetMcs`: The target MCS index + * values: 0-9 (default: 8) ### `MeasurementBasedApApTPC` This algorithm tries to assign the Tx power of the OWF APs by getting a set of @@ -87,3 +93,7 @@ levels of these APs will be determined by the following steps: Parameters: * `mode`: "measure_ap_ap" +* `coverageThreshold`: Coverage threshold between APs in dBm + * values: int < 30 (default: -70) +* `nthSmallestRssi`: the nth smallest RSSI that is used for tx power calculation + * values: int >= 0 (default: 0) diff --git a/src/main/java/com/facebook/openwifirrm/RRMAlgorithm.java b/src/main/java/com/facebook/openwifirrm/RRMAlgorithm.java index bea57e0..f551cd6 100644 --- a/src/main/java/com/facebook/openwifirrm/RRMAlgorithm.java +++ b/src/main/java/com/facebook/openwifirrm/RRMAlgorithm.java @@ -186,24 +186,27 @@ public class RRMAlgorithm { logger.info("Using default algorithm mode..."); // fall through case UnmanagedApAwareChannelOptimizer.ALGORITHM_ID: - optimizer = new UnmanagedApAwareChannelOptimizer( + optimizer = UnmanagedApAwareChannelOptimizer.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; case RandomChannelInitializer.ALGORITHM_ID: - optimizer = new RandomChannelInitializer( + optimizer = RandomChannelInitializer.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; case LeastUsedChannelOptimizer.ALGORITHM_ID: - optimizer = new LeastUsedChannelOptimizer( + optimizer = LeastUsedChannelOptimizer.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; } @@ -233,31 +236,35 @@ public class RRMAlgorithm { logger.info("Using default algorithm mode..."); // fall through case MeasurementBasedApApTPC.ALGORITHM_ID: - optimizer = new MeasurementBasedApApTPC( + optimizer = MeasurementBasedApApTPC.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; case RandomTxPowerInitializer.ALGORITHM_ID: - optimizer = new RandomTxPowerInitializer( + optimizer = RandomTxPowerInitializer.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; case MeasurementBasedApClientTPC.ALGORITHM_ID: - optimizer = new MeasurementBasedApClientTPC( + optimizer = MeasurementBasedApClientTPC.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; case LocationBasedOptimalTPC.ALGORITHM_ID: - optimizer = new LocationBasedOptimalTPC( + optimizer = LocationBasedOptimalTPC.makeWithArgs( modeler.getDataModelCopy(), zone, - deviceDataManager + deviceDataManager, + args ); break; } diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/channel/LeastUsedChannelOptimizer.java b/src/main/java/com/facebook/openwifirrm/optimizers/channel/LeastUsedChannelOptimizer.java index b6510ce..cac731c 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/channel/LeastUsedChannelOptimizer.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/channel/LeastUsedChannelOptimizer.java @@ -45,6 +45,16 @@ public class LeastUsedChannelOptimizer extends ChannelOptimizer { /** The PRNG instance. */ protected final Random rng = new Random(); + /** Factory method to parse generic args map into the proper constructor */ + public static LeastUsedChannelOptimizer makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + return new LeastUsedChannelOptimizer(model, zone, deviceDataManager); + } + /** Constructor. */ public LeastUsedChannelOptimizer( DataModel model, diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/channel/RandomChannelInitializer.java b/src/main/java/com/facebook/openwifirrm/optimizers/channel/RandomChannelInitializer.java index 8d94b27..074e591 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/channel/RandomChannelInitializer.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/channel/RandomChannelInitializer.java @@ -38,11 +38,36 @@ public class RandomChannelInitializer extends ChannelOptimizer { /** The RRM algorithm ID. */ public static final String ALGORITHM_ID = "random"; + /** Default value for setDifferentChannelPerAp */ + public static final boolean DEFAULT_SET_DIFFERENT_CHANNEL_PER_AP = false; + /** The PRNG instance. */ private final Random rng; /** Whether to set a different value per AP or use a single value for all APs */ - private final boolean setDifferentChannelsPerAp; + private final boolean setDifferentChannelPerAp; + + /** Factory method to parse generic args map into the proper constructor */ + public static RandomChannelInitializer makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + boolean setDifferentChannelPerAp = DEFAULT_SET_DIFFERENT_CHANNEL_PER_AP; + + String arg; + if ((arg = args.get("setDifferentChannelPerAp")) != null) { + setDifferentChannelPerAp = Boolean.parseBoolean(arg); + } + + return new RandomChannelInitializer( + model, + zone, + deviceDataManager, + setDifferentChannelPerAp + ); + } /** Constructor. */ public RandomChannelInitializer( @@ -50,7 +75,12 @@ public class RandomChannelInitializer extends ChannelOptimizer { String zone, DeviceDataManager deviceDataManager ) { - this(model, zone, deviceDataManager, false); + this( + model, + zone, + deviceDataManager, + DEFAULT_SET_DIFFERENT_CHANNEL_PER_AP + ); } /** Constructor (allows setting different channel per AP) */ @@ -58,13 +88,13 @@ public class RandomChannelInitializer extends ChannelOptimizer { DataModel model, String zone, DeviceDataManager deviceDataManager, - boolean setDifferentChannelsPerAp + boolean setDifferentChannelPerAp ) { this( model, zone, deviceDataManager, - setDifferentChannelsPerAp, + setDifferentChannelPerAp, new Random() ); } @@ -77,11 +107,11 @@ public class RandomChannelInitializer extends ChannelOptimizer { DataModel model, String zone, DeviceDataManager deviceDataManager, - boolean setDifferentChannelsPerAp, + boolean setDifferentChannelPerAp, Random rng ) { super(model, zone, deviceDataManager); - this.setDifferentChannelsPerAp = setDifferentChannelsPerAp; + this.setDifferentChannelPerAp = setDifferentChannelPerAp; this.rng = rng; } @@ -143,13 +173,13 @@ public class RandomChannelInitializer extends ChannelOptimizer { } // Randomly assign all the devices to the same channel if - // setDifferentChannelsPerAp is false otherwise, assigns + // setDifferentChannelPerAp is false otherwise, assigns // each device to a random channel int defaultChannelIndex = rng.nextInt(availableChannelsList.size()); for (String serialNumber : entry.getValue()) { int newChannel = availableChannelsList.get( - this.setDifferentChannelsPerAp + this.setDifferentChannelPerAp ? rng.nextInt(availableChannelsList.size()) : defaultChannelIndex ); diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/channel/UnmanagedApAwareChannelOptimizer.java b/src/main/java/com/facebook/openwifirrm/optimizers/channel/UnmanagedApAwareChannelOptimizer.java index d11ab9d..c62aa9d 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/channel/UnmanagedApAwareChannelOptimizer.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/channel/UnmanagedApAwareChannelOptimizer.java @@ -39,6 +39,20 @@ public class UnmanagedApAwareChannelOptimizer /** The default weight for nonOWF APs. */ private static final int DEFAULT_WEIGHT = 2; + /** Factory method to parse generic args map into the proper constructor */ + public static UnmanagedApAwareChannelOptimizer makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + return new UnmanagedApAwareChannelOptimizer( + model, + zone, + deviceDataManager + ); + } + /** Constructor. */ public UnmanagedApAwareChannelOptimizer( DataModel model, diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/LocationBasedOptimalTPC.java b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/LocationBasedOptimalTPC.java index 67cea98..e9b755b 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/LocationBasedOptimalTPC.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/LocationBasedOptimalTPC.java @@ -38,6 +38,16 @@ public class LocationBasedOptimalTPC extends TPC { /** The RRM algorithm ID. */ public static final String ALGORITHM_ID = "location_optimal"; + /** Factory method to parse generic args map into the proper constructor */ + public static LocationBasedOptimalTPC makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + return new LocationBasedOptimalTPC(model, zone, deviceDataManager); + } + /** Constructor. */ public LocationBasedOptimalTPC( DataModel model, diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApApTPC.java b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApApTPC.java index 4b2fd3e..cf708cb 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApApTPC.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApApTPC.java @@ -64,6 +64,62 @@ public class MeasurementBasedApApTPC extends TPC { /** Nth smallest RSSI (zero-indexed) is used for Tx power calculation */ private final int nthSmallestRssi; // TODO non-zero values untested + /** Factory method to parse generic args map into the proper constructor */ + public static MeasurementBasedApApTPC makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + int coverageThreshold = DEFAULT_COVERAGE_THRESHOLD; + int nthSmallestRssi = DEFAULT_NTH_SMALLEST_RSSI; + + String arg; + if ((arg = args.get("coverageThreshold")) != null) { + try { + int parsedCoverageThreshold = Integer.parseInt(arg); + if (parsedCoverageThreshold > 30) { + logger.error( + "Invalid value passed for coverageThreshold - must be less than 30. Using default value." + ); + } else { + coverageThreshold = parsedCoverageThreshold; + } + } catch (NumberFormatException e) { + logger.error( + "Invalid integer passed to parameter coverageThreshold, using default value", + e + ); + } + } + + if ((arg = args.get("nthSmallestRssi")) != null) { + try { + int parsedNthSmallestRssi = Integer.parseInt(arg); + if (parsedNthSmallestRssi < 0) { + logger.error( + "Invalid value passed for nthSmallestRssi - must be greater than 0. Using default value." + ); + } else { + nthSmallestRssi = parsedNthSmallestRssi; + } + } catch (NumberFormatException e) { + logger.error( + "Invalid integer passed to parameter nthSmallestRssi, using default value", + e + ); + } + } + + return new MeasurementBasedApApTPC( + model, + zone, + deviceDataManager, + coverageThreshold, + nthSmallestRssi + ); + } + /** Constructor. */ public MeasurementBasedApApTPC( DataModel model, diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApClientTPC.java b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApClientTPC.java index 64cd796..df1909e 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApClientTPC.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/MeasurementBasedApClientTPC.java @@ -61,6 +61,43 @@ public class MeasurementBasedApClientTPC extends TPC { /** The target MCS index. */ private final int targetMcs; + /** Factory method to parse generic args map into the proper constructor */ + public static MeasurementBasedApClientTPC makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + int targetMcs = DEFAULT_TARGET_MCS; + + String arg; + if ((arg = args.get("targetMcs")) != null) { + + try { + int parsedTargetMcs = Integer.parseInt(arg); + if (targetMcs < 0) { + logger.error( + "Invalid value passed for targetMcs - must be greater than 0. Using default value." + ); + } else { + targetMcs = parsedTargetMcs; + } + } catch (NumberFormatException e) { + logger.error( + "Invalid integer passed to parameter targetMcs, using default value", + e + ); + } + } + + return new MeasurementBasedApClientTPC( + model, + zone, + deviceDataManager, + targetMcs + ); + } + /** Constructor (uses default target MCS index). */ public MeasurementBasedApClientTPC( DataModel model, diff --git a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/RandomTxPowerInitializer.java b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/RandomTxPowerInitializer.java index 0f99eda..3e40a8d 100644 --- a/src/main/java/com/facebook/openwifirrm/optimizers/tpc/RandomTxPowerInitializer.java +++ b/src/main/java/com/facebook/openwifirrm/optimizers/tpc/RandomTxPowerInitializer.java @@ -31,19 +31,54 @@ public class RandomTxPowerInitializer extends TPC { /** The RRM algorithm ID. */ public static final String ALGORITHM_ID = "random"; + /** Default value for setDifferentTxPowerPerAp */ + public static final boolean DEFAULT_SET_DIFFERENT_TX_POWER_PER_AP = + false; + /** The PRNG instance. */ private final Random rng; /** Whether to set a different value per AP or use a single value for all APs */ private final boolean setDifferentTxPowerPerAp; - /** Constructor (uses random tx power). */ + /** Factory method to parse generic args map into the proper constructor */ + public static RandomTxPowerInitializer makeWithArgs( + DataModel model, + String zone, + DeviceDataManager deviceDataManager, + Map args + ) { + boolean setDifferentTxPowerPerAp = + DEFAULT_SET_DIFFERENT_TX_POWER_PER_AP; + + String arg; + if ((arg = args.get("setDifferentTxPowerPerAp")) != null) { + setDifferentTxPowerPerAp = Boolean.parseBoolean(arg); + } + + return new RandomTxPowerInitializer( + model, + zone, + deviceDataManager, + setDifferentTxPowerPerAp + ); + } + + /** + * Constructor (uses random tx power per AP and allows passing in a custom + * Random class to allow seeding). + */ public RandomTxPowerInitializer( DataModel model, String zone, DeviceDataManager deviceDataManager ) { - this(model, zone, deviceDataManager, false); + this( + model, + zone, + deviceDataManager, + DEFAULT_SET_DIFFERENT_TX_POWER_PER_AP + ); } /** Constructor (uses random tx power per AP). */