118 lines
3.4 KiB
Swift
118 lines
3.4 KiB
Swift
import Foundation
|
|
import Logging
|
|
import OrderedCollections
|
|
import Routes
|
|
|
|
public extension Capacitor.Request {
|
|
|
|
static let standardCapacitorSizes = OrderedSet([
|
|
5, 7.5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
|
|
])
|
|
|
|
func respond(logger: Logger) async throws -> Capacitor.Response {
|
|
switch self {
|
|
case let .size(request):
|
|
return try calculateSize(request, logger)
|
|
case let .test(request):
|
|
return try calculateCapcitance(request, logger)
|
|
}
|
|
}
|
|
|
|
private func calculateCapcitance(
|
|
_ request: Capacitor.Request.TestRequest,
|
|
_ logger: Logger
|
|
) throws -> Capacitor.Response {
|
|
try request.validate()
|
|
|
|
let capacitance = (2653 * request.startWindingAmps) / request.runToCommonVoltage
|
|
logger.debug("Test Capacitor calculated capacitance: \(capacitance)")
|
|
|
|
var ratedComparison: Capacitor.RatedComparison?
|
|
|
|
if let rating = request.ratedCapacitorSize {
|
|
let rating = Double(rating)
|
|
let deviation = ((capacitance - rating) / rating) * 100.0
|
|
logger.debug("Test Capacitor calculated deviation: \(deviation)")
|
|
// let positiveDeviation = deviation.ensurePostive()
|
|
|
|
ratedComparison = .init(
|
|
value: Int(rating),
|
|
isInRange: abs(deviation) <= 6,
|
|
percentDeviation: deviation
|
|
)
|
|
}
|
|
|
|
return .test(result: .init(
|
|
capacitance: capacitance,
|
|
tolerance: .init(capacitance: capacitance),
|
|
ratedComparison: ratedComparison
|
|
))
|
|
}
|
|
|
|
private func calculateSize(
|
|
_ request: Capacitor.Request.SizeRequest,
|
|
_ logger: Logger
|
|
) throws -> Capacitor.Response {
|
|
try request.validate()
|
|
|
|
let frequency = 60.0
|
|
let phaseAngle = acos(request.powerFactor)
|
|
let reactiveComponent = request.runningAmps * sin(phaseAngle)
|
|
let capacitance = (reactiveComponent * 1_000_000) / (2 * Double.pi * frequency * request.lineVoltage)
|
|
|
|
logger.debug("Calculate capacitor size capacitance: \(capacitance)")
|
|
|
|
let standardSize = Self.standardCapacitorSizes.first(where: { $0 >= capacitance })
|
|
?? Self.standardCapacitorSizes.last!
|
|
|
|
logger.debug("Calculate capacitor standard size: \(standardSize)")
|
|
|
|
return .size(result: .init(
|
|
capacitance: capacitance,
|
|
standardSize: standardSize,
|
|
tolerance: .init(capacitance: capacitance)
|
|
))
|
|
}
|
|
|
|
}
|
|
|
|
private extension Capacitor.Tolerance {
|
|
init(capacitance: Double) {
|
|
// +- 6% tolerance
|
|
self.init(
|
|
minimum: capacitance * 0.96,
|
|
maximum: capacitance * 1.06
|
|
)
|
|
}
|
|
}
|
|
|
|
private extension Capacitor.Request.TestRequest {
|
|
func validate() throws {
|
|
guard startWindingAmps > 0 else {
|
|
throw ValidationError(message: "Start winding amps should be greater than 0.")
|
|
}
|
|
guard runToCommonVoltage > 0 else {
|
|
throw ValidationError(message: "Run to common voltage should be greater than 0.")
|
|
}
|
|
if let ratedCapacitorSize {
|
|
guard ratedCapacitorSize > 0 else {
|
|
throw ValidationError(message: "Run to common voltage should be greater than 0.")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension Capacitor.Request.SizeRequest {
|
|
func validate() throws {
|
|
guard runningAmps > 0 else {
|
|
throw ValidationError(message: "Running amps should be greater than 0.")
|
|
}
|
|
guard lineVoltage > 0 else {
|
|
throw ValidationError(message: "Line voltage should be greater than 0.")
|
|
}
|
|
guard powerFactor > 0, powerFactor < 1.01 else {
|
|
throw ValidationError(message: "powerFactor should be greater than 0 and at max 1.")
|
|
}
|
|
}
|
|
}
|