discoverBridges static method

Future<List<DiscoveredBridge>> discoverBridges({
  1. Directory? savedBridgesDir,
  2. bool writeToLocal = true,
  3. String decrypter(
    1. String ciphertext
    )?,
})

Searches the network for Philips Hue bridges.

Returns a list of DiscoveredBridge objects. These contain the IP address of the bridge and a partial ID of the bridge.

If saved bridges are not saved to the default folder, provide their location with savedBridgesDir.

decrypter When the bridge data is read from local storage, it is decrypted. This parameter allows you to provide your own decryption method. This will be used in addition to the default decryption method. This will be performed after the default decryption method.

Implementation

static Future<List<DiscoveredBridge>> discoverBridges({
  Directory? savedBridgesDir,
  bool writeToLocal = true,
  String Function(String ciphertext)? decrypter,
}) async {
  /// The bridges already saved to this device.
  List<Bridge> savedBridges;

  if (kIsWeb) {
    // cookies instead of local storage (not yet implemented)
    savedBridges = [];
  } else {
    savedBridges = await fetchSavedBridges(
      decrypter: decrypter,
      directory: savedBridgesDir,
    );
  }

  /// Bridges found using MDNS.
  List<DiscoveredBridge> bridgesFromMdns;
  if (kIsWeb) {
    // mDNS does not work on web.
    bridgesFromMdns = [];
  } else {
    bridgesFromMdns = await BridgeDiscoveryService.discoverBridgesMdns();
  }

  /// Bridges found using the endpoint method.
  List<DiscoveredBridge> bridgesFromEndpoint =
      await BridgeDiscoveryService.discoverBridgesEndpoint();

  // Remove duplicates from the two search methods.
  Set<DiscoveredBridge> uniqueValues = {};
  for (final DiscoveredBridge bridgeFromMdns in bridgesFromMdns) {
    for (final DiscoveredBridge bridgeFromEndpoint in bridgesFromEndpoint) {
      if (bridgeFromMdns.ipAddress == bridgeFromEndpoint.ipAddress) {
        bridgeFromMdns.rawIdFromEndpoint =
            bridgeFromEndpoint.rawIdFromEndpoint;
        bridgesFromEndpoint.remove(bridgeFromEndpoint);
        break;
      }
    }
    uniqueValues.add(bridgeFromMdns);
  }
  uniqueValues.addAll(bridgesFromEndpoint);

  if (savedBridges.isEmpty) return uniqueValues.toList();

  List<DiscoveredBridge> newBridges = [];

  // Remove the bridges that are already saved to the device from the search
  // results.
  for (final DiscoveredBridge discoveredBridge in uniqueValues) {
    bool isSaved = false;

    for (Bridge bridge in savedBridges) {
      if (bridge.ipAddress != null &&
          bridge.ipAddress == discoveredBridge.ipAddress) {
        isSaved = true;
        break;
      }
    }

    if (!isSaved) {
      newBridges.add(discoveredBridge);
    }
  }

  // Keep locally saved bridges up to date.
  if (writeToLocal) {
    for (final DiscoveredBridge newBridge in newBridges) {
      // This will go through each of the bridges who's IP address have just
      // been collected and tries to connect to them. If there is a successful
      // connection, then this isn't the first time contact has been made with
      // the bridge. In this case, the file will be overridden with the new IP
      // address.
      await firstContact(
        bridgeIpAddr: newBridge.ipAddress,
        savedBridgesDir: savedBridgesDir,
        writeToLocal: writeToLocal,
        controller: DiscoveryTimeoutController(timeoutSeconds: 1),
      );
    }
  }

  return newBridges;
}