import Logging import Routes public extension DehumidifierSize.Request { private static let minTempEfficiency = 65.0 private static let minRHEfficiency = 60.0 private static let dehumidifierSizes = [ 33: "https://www.santa-fe-products.com/product/ultramd33-dehumidifier/", 70: "https://www.santa-fe-products.com/product/santa-fe-ultra70-dehumidifier/", 100: "https://www.santa-fe-products.com/product/ultra98-dehumidifier/", 118: "https://www.santa-fe-products.com/product/ultra120-dehumidifier/", 155: "https://www.santa-fe-products.com/product/ultra1559dehumidifier/", 205: "https://www.santa-fe-products.com/product/ultra205-dehumidifier/" ] func respond(_ logger: Logger) async throws -> DehumidifierSize.Response { try validate() let pintsPerDay = (latentLoad / 1054) * 24 var capacityFactor = 1.0 var warnings: [String] = [] if temperature < Self.minTempEfficiency { if temperature < 60 { capacityFactor *= 0.5 warnings.append( "Very low temperature will severely reduce dehumidifier efficiency." ) } else { capacityFactor *= 0.7 warnings.append( "Low temperature will severely reduce dehumidifier efficiency." ) } } if humidity < Self.minRHEfficiency { capacityFactor *= 0.8 warnings.append( "Low relative humidity will significantly reduce moisture removal rate." ) } let requiredCapacity = pintsPerDay / capacityFactor addDefaultWarnings(&warnings) // TODO: Return an error if required capacity is larger than biggest residential dehumidifier. // TODO: Return early here ?? if requiredCapacity > 205 { logger.debug("Required capacity exceeds residential unit.") warnings.append( "Required capacity exceeds largest standard residential unit - consider multiple units or a commercial system" ) } let (recommendedSize, recommendedUrl) = parseRecommendedSize(requiredCapacity) logger.debug("Recommend size: \(recommendedSize)") return .init( requiredCapacity: requiredCapacity, pintsPerDay: pintsPerDay, recommendedSize: recommendedSize, recommendedUrl: recommendedUrl, warnings: warnings ) } private func validate() throws { guard latentLoad > 0 else { throw DehumidiferSizeValidationError.latentLoadShouldBeGreaterThanZero } guard temperature > 0 else { throw DehumidiferSizeValidationError.temperatureShouldBeGreaterThanZero } guard humidity > 0 else { throw DehumidiferSizeValidationError.humidityShouldBeGreaterThanZero } } private func parseRecommendedSize(_ requiredCapacity: Double) -> (Int, String) { // TODO: Return an error if required capacity is larger than biggest residential dehumidifier. // Ensure the keys are sorted, otherwise it gives unpredictable results. let key = Self.dehumidifierSizes.keys.sorted() .first { Double($0) >= requiredCapacity } // Use the largest dehumidifier because the requirement is larger than the largest key. ?? 255 return (key, Self.dehumidifierSizes[key]!) } private func addDefaultWarnings(_ warnings: inout [String]) { // High humidity warnings if humidity > 65 { warnings.append( "High relative humidity - unit may need to run continuously." ) } if humidity > 80 { warnings.append( "Extreme humidity levels - address moisture sources and improve ventilation before dehumidification." ) } // Temperature warnings if temperature < 60 { warnings.append( "Temperature too low for effective dehumidification - consider raising space temperature first." ) } } } enum DehumidiferSizeValidationError: Error { case latentLoadShouldBeGreaterThanZero case temperatureShouldBeGreaterThanZero case humidityShouldBeGreaterThanZero }