WIP: Inital duct rectangular form, needs better thought out.
This commit is contained in:
@@ -18,6 +18,7 @@ public struct DatabaseClient: Sendable {
|
|||||||
public var equipment: Equipment
|
public var equipment: Equipment
|
||||||
public var componentLoss: ComponentLoss
|
public var componentLoss: ComponentLoss
|
||||||
public var effectiveLength: EffectiveLengthClient
|
public var effectiveLength: EffectiveLengthClient
|
||||||
|
// public var rectangularDuct: RectangularDuct
|
||||||
public var users: Users
|
public var users: Users
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ extension DatabaseClient: TestDependencyKey {
|
|||||||
equipment: .testValue,
|
equipment: .testValue,
|
||||||
componentLoss: .testValue,
|
componentLoss: .testValue,
|
||||||
effectiveLength: .testValue,
|
effectiveLength: .testValue,
|
||||||
|
// rectangularDuct: .testValue,
|
||||||
users: .testValue
|
users: .testValue
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,6 +42,7 @@ extension DatabaseClient: TestDependencyKey {
|
|||||||
equipment: .live(database: database),
|
equipment: .live(database: database),
|
||||||
componentLoss: .live(database: database),
|
componentLoss: .live(database: database),
|
||||||
effectiveLength: .live(database: database),
|
effectiveLength: .live(database: database),
|
||||||
|
// rectangularDuct: .live(database: database),
|
||||||
users: .live(database: database)
|
users: .live(database: database)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -67,6 +70,7 @@ extension DatabaseClient.Migrations: DependencyKey {
|
|||||||
EquipmentInfo.Migrate(),
|
EquipmentInfo.Migrate(),
|
||||||
Room.Migrate(),
|
Room.Migrate(),
|
||||||
EffectiveLength.Migrate(),
|
EffectiveLength.Migrate(),
|
||||||
|
// DuctSizing.RectangularDuct.Migrate(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
175
Sources/DatabaseClient/RectangularDuct.swift
Normal file
175
Sources/DatabaseClient/RectangularDuct.swift
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
// import Dependencies
|
||||||
|
// import DependenciesMacros
|
||||||
|
// import Fluent
|
||||||
|
// import Foundation
|
||||||
|
// import ManualDCore
|
||||||
|
//
|
||||||
|
// extension DatabaseClient {
|
||||||
|
// @DependencyClient
|
||||||
|
// public struct RectangularDuct: Sendable {
|
||||||
|
// public var create:
|
||||||
|
// @Sendable (DuctSizing.RectangularDuct.Create) async throws -> DuctSizing.RectangularDuct
|
||||||
|
// public var delete: @Sendable (DuctSizing.RectangularDuct.ID) async throws -> Void
|
||||||
|
// public var fetch: @Sendable (Room.ID) async throws -> [DuctSizing.RectangularDuct]
|
||||||
|
// public var get:
|
||||||
|
// @Sendable (DuctSizing.RectangularDuct.ID) async throws -> DuctSizing.RectangularDuct?
|
||||||
|
// public var update:
|
||||||
|
// @Sendable (DuctSizing.RectangularDuct.ID, DuctSizing.RectangularDuct.Update) async throws ->
|
||||||
|
// DuctSizing.RectangularDuct
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// extension DatabaseClient.RectangularDuct: TestDependencyKey {
|
||||||
|
// public static let testValue = Self()
|
||||||
|
//
|
||||||
|
// public static func live(database: any Database) -> Self {
|
||||||
|
// .init(
|
||||||
|
// create: { request in
|
||||||
|
// try request.validate()
|
||||||
|
// let model = request.toModel()
|
||||||
|
// try await model.save(on: database)
|
||||||
|
// return try model.toDTO()
|
||||||
|
// },
|
||||||
|
// delete: { id in
|
||||||
|
// guard let model = try await RectangularDuctModel.find(id, on: database) else {
|
||||||
|
// throw NotFoundError()
|
||||||
|
// }
|
||||||
|
// try await model.delete(on: database)
|
||||||
|
// },
|
||||||
|
// fetch: { roomID in
|
||||||
|
// try await RectangularDuctModel.query(on: database)
|
||||||
|
// .with(\.$room)
|
||||||
|
// .filter(\.$room.$id == roomID)
|
||||||
|
// .all()
|
||||||
|
// .map { try $0.toDTO() }
|
||||||
|
// },
|
||||||
|
// get: { id in
|
||||||
|
// try await RectangularDuctModel.find(id, on: database)
|
||||||
|
// .map { try $0.toDTO() }
|
||||||
|
// },
|
||||||
|
// update: { id, updates in
|
||||||
|
// guard let model = try await RectangularDuctModel.find(id, on: database) else {
|
||||||
|
// throw NotFoundError()
|
||||||
|
// }
|
||||||
|
// try updates.validate()
|
||||||
|
// model.applyUpdates(updates)
|
||||||
|
// if model.hasChanges {
|
||||||
|
// try await model.save(on: database)
|
||||||
|
// }
|
||||||
|
// return try model.toDTO()
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// extension DuctSizing.RectangularDuct.Create {
|
||||||
|
//
|
||||||
|
// func validate() throws(ValidationError) {
|
||||||
|
// guard height > 0 else {
|
||||||
|
// throw ValidationError("Rectangular duct size height should be greater than 0.")
|
||||||
|
// }
|
||||||
|
// if let register {
|
||||||
|
// guard register > 0 else {
|
||||||
|
// throw ValidationError("Rectangular duct size register should be greater than 0.")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func toModel() -> RectangularDuctModel {
|
||||||
|
// .init(roomID: roomID, height: height)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// extension DuctSizing.RectangularDuct.Update {
|
||||||
|
//
|
||||||
|
// func validate() throws(ValidationError) {
|
||||||
|
// if let height {
|
||||||
|
// guard height > 0 else {
|
||||||
|
// throw ValidationError("Rectangular duct size height should be greater than 0.")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if let register {
|
||||||
|
// guard register > 0 else {
|
||||||
|
// throw ValidationError("Rectangular duct size register should be greater than 0.")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// extension DuctSizing.RectangularDuct {
|
||||||
|
// struct Migrate: AsyncMigration {
|
||||||
|
// let name = "CreateRectangularDuct"
|
||||||
|
//
|
||||||
|
// func prepare(on database: any Database) async throws {
|
||||||
|
// try await database.schema(RectangularDuctModel.schema)
|
||||||
|
// .id()
|
||||||
|
// .field("register", .int8)
|
||||||
|
// .field("height", .int8, .required)
|
||||||
|
// .field("roomID", .uuid, .required, .references(RoomModel.schema, "id", onDelete: .cascade))
|
||||||
|
// .field("createdAt", .datetime)
|
||||||
|
// .field("updatedAt", .datetime)
|
||||||
|
// .create()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func revert(on database: any Database) async throws {
|
||||||
|
// try await database.schema(RectangularDuctModel.schema).delete()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final class RectangularDuctModel: Model, @unchecked Sendable {
|
||||||
|
//
|
||||||
|
// static let schema = "rectangularDuct"
|
||||||
|
//
|
||||||
|
// @ID(key: .id)
|
||||||
|
// var id: UUID?
|
||||||
|
//
|
||||||
|
// @Parent(key: "roomID")
|
||||||
|
// var room: RoomModel
|
||||||
|
//
|
||||||
|
// @Field(key: "height")
|
||||||
|
// var height: Int
|
||||||
|
//
|
||||||
|
// @Field(key: "register")
|
||||||
|
// var register: Int?
|
||||||
|
//
|
||||||
|
// @Timestamp(key: "createdAt", on: .create, format: .iso8601)
|
||||||
|
// var createdAt: Date?
|
||||||
|
//
|
||||||
|
// @Timestamp(key: "updatedAt", on: .update, format: .iso8601)
|
||||||
|
// var updatedAt: Date?
|
||||||
|
//
|
||||||
|
// init() {}
|
||||||
|
//
|
||||||
|
// init(
|
||||||
|
// id: UUID? = nil,
|
||||||
|
// roomID: Room.ID,
|
||||||
|
// register: Int? = nil,
|
||||||
|
// height: Int
|
||||||
|
// ) {
|
||||||
|
// self.id = id
|
||||||
|
// $room.id = roomID
|
||||||
|
// self.register = register
|
||||||
|
// self.height = height
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func toDTO() throws -> DuctSizing.RectangularDuct {
|
||||||
|
// return try .init(
|
||||||
|
// id: requireID(),
|
||||||
|
// roomID: $room.id,
|
||||||
|
// register: register,
|
||||||
|
// height: height,
|
||||||
|
// createdAt: createdAt!,
|
||||||
|
// updatedAt: updatedAt!
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func applyUpdates(_ updates: DuctSizing.RectangularDuct.Update) {
|
||||||
|
// if let height = updates.height, height != self.height {
|
||||||
|
// self.height = height
|
||||||
|
// }
|
||||||
|
// if let register = updates.register, register != self.register {
|
||||||
|
// self.register = register
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -38,6 +38,7 @@ extension DatabaseClient.Rooms: TestDependencyKey {
|
|||||||
try await RoomModel.query(on: database)
|
try await RoomModel.query(on: database)
|
||||||
.with(\.$project)
|
.with(\.$project)
|
||||||
.filter(\.$project.$id, .equal, projectID)
|
.filter(\.$project.$id, .equal, projectID)
|
||||||
|
.sort(\.$name, .ascending)
|
||||||
.all()
|
.all()
|
||||||
.map { try $0.toDTO() }
|
.map { try $0.toDTO() }
|
||||||
},
|
},
|
||||||
@@ -135,6 +136,7 @@ extension Room {
|
|||||||
.field("coolingTotal", .double, .required)
|
.field("coolingTotal", .double, .required)
|
||||||
.field("coolingSensible", .double)
|
.field("coolingSensible", .double)
|
||||||
.field("registerCount", .int8, .required)
|
.field("registerCount", .int8, .required)
|
||||||
|
.field("rectangularSizes", .array)
|
||||||
.field("createdAt", .datetime)
|
.field("createdAt", .datetime)
|
||||||
.field("updatedAt", .datetime)
|
.field("updatedAt", .datetime)
|
||||||
.field(
|
.field(
|
||||||
@@ -172,6 +174,9 @@ final class RoomModel: Model, @unchecked Sendable {
|
|||||||
@Field(key: "registerCount")
|
@Field(key: "registerCount")
|
||||||
var registerCount: Int
|
var registerCount: Int
|
||||||
|
|
||||||
|
@Field(key: "rectangularSizes")
|
||||||
|
var rectangularSizes: [DuctSizing.RectangularDuct]?
|
||||||
|
|
||||||
@Timestamp(key: "createdAt", on: .create, format: .iso8601)
|
@Timestamp(key: "createdAt", on: .create, format: .iso8601)
|
||||||
var createdAt: Date?
|
var createdAt: Date?
|
||||||
|
|
||||||
@@ -190,6 +195,7 @@ final class RoomModel: Model, @unchecked Sendable {
|
|||||||
coolingTotal: Double,
|
coolingTotal: Double,
|
||||||
coolingSensible: Double? = nil,
|
coolingSensible: Double? = nil,
|
||||||
registerCount: Int,
|
registerCount: Int,
|
||||||
|
rectangularSizes: [DuctSizing.RectangularDuct]? = nil,
|
||||||
createdAt: Date? = nil,
|
createdAt: Date? = nil,
|
||||||
updatedAt: Date? = nil,
|
updatedAt: Date? = nil,
|
||||||
projectID: Project.ID
|
projectID: Project.ID
|
||||||
@@ -200,6 +206,7 @@ final class RoomModel: Model, @unchecked Sendable {
|
|||||||
self.coolingTotal = coolingTotal
|
self.coolingTotal = coolingTotal
|
||||||
self.coolingSensible = coolingSensible
|
self.coolingSensible = coolingSensible
|
||||||
self.registerCount = registerCount
|
self.registerCount = registerCount
|
||||||
|
self.rectangularSizes = rectangularSizes
|
||||||
self.createdAt = createdAt
|
self.createdAt = createdAt
|
||||||
self.updatedAt = updatedAt
|
self.updatedAt = updatedAt
|
||||||
$project.id = projectID
|
$project.id = projectID
|
||||||
@@ -214,6 +221,7 @@ final class RoomModel: Model, @unchecked Sendable {
|
|||||||
coolingTotal: coolingTotal,
|
coolingTotal: coolingTotal,
|
||||||
coolingSensible: coolingSensible,
|
coolingSensible: coolingSensible,
|
||||||
registerCount: registerCount,
|
registerCount: registerCount,
|
||||||
|
rectangularSizes: rectangularSizes,
|
||||||
createdAt: createdAt!,
|
createdAt: createdAt!,
|
||||||
updatedAt: updatedAt!
|
updatedAt: updatedAt!
|
||||||
)
|
)
|
||||||
@@ -236,6 +244,9 @@ final class RoomModel: Model, @unchecked Sendable {
|
|||||||
if let registerCount = updates.registerCount, registerCount != self.registerCount {
|
if let registerCount = updates.registerCount, registerCount != self.registerCount {
|
||||||
self.registerCount = registerCount
|
self.registerCount = registerCount
|
||||||
}
|
}
|
||||||
|
if let rectangularSizes = updates.rectangularSizes, rectangularSizes != self.rectangularSizes {
|
||||||
|
self.rectangularSizes = rectangularSizes
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public struct ManualDClient: Sendable {
|
|||||||
projectSHR: Double,
|
projectSHR: Double,
|
||||||
logger: Logger? = nil
|
logger: Logger? = nil
|
||||||
) async throws -> [DuctSizing.RoomContainer] {
|
) async throws -> [DuctSizing.RoomContainer] {
|
||||||
|
|
||||||
var registerIDCount = 1
|
var registerIDCount = 1
|
||||||
var retval: [DuctSizing.RoomContainer] = []
|
var retval: [DuctSizing.RoomContainer] = []
|
||||||
let totalHeatingLoad = rooms.totalHeatingLoad
|
let totalHeatingLoad = rooms.totalHeatingLoad
|
||||||
@@ -38,6 +39,18 @@ public struct ManualDClient: Sendable {
|
|||||||
)
|
)
|
||||||
|
|
||||||
for n in 1...room.registerCount {
|
for n in 1...room.registerCount {
|
||||||
|
|
||||||
|
var rectangularWidth: Int? = nil
|
||||||
|
let rectangularSize = room.rectangularSizes?
|
||||||
|
.first(where: { $0.register == nil || $0.register == n })
|
||||||
|
|
||||||
|
if let rectangularSize {
|
||||||
|
let response = try await self.equivalentRectangularDuct(
|
||||||
|
.init(round: sizes.finalSize, height: rectangularSize.height)
|
||||||
|
)
|
||||||
|
rectangularWidth = response.width
|
||||||
|
}
|
||||||
|
|
||||||
retval.append(
|
retval.append(
|
||||||
.init(
|
.init(
|
||||||
registerID: "SR-\(registerIDCount)",
|
registerID: "SR-\(registerIDCount)",
|
||||||
@@ -51,7 +64,9 @@ public struct ManualDClient: Sendable {
|
|||||||
roundSize: sizes.ductulatorSize,
|
roundSize: sizes.ductulatorSize,
|
||||||
finalSize: sizes.finalSize,
|
finalSize: sizes.finalSize,
|
||||||
velocity: sizes.velocity,
|
velocity: sizes.velocity,
|
||||||
flexSize: sizes.flexSize
|
flexSize: sizes.flexSize,
|
||||||
|
rectangularSize: rectangularSize,
|
||||||
|
rectangularWidth: rectangularWidth
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
registerIDCount += 1
|
registerIDCount += 1
|
||||||
|
|||||||
@@ -3,6 +3,21 @@ import Foundation
|
|||||||
|
|
||||||
public enum DuctSizing {
|
public enum DuctSizing {
|
||||||
|
|
||||||
|
public struct RectangularDuct: Codable, Equatable, Sendable {
|
||||||
|
|
||||||
|
public let register: Int?
|
||||||
|
public let height: Int
|
||||||
|
|
||||||
|
public init(
|
||||||
|
register: Int? = nil,
|
||||||
|
height: Int,
|
||||||
|
) {
|
||||||
|
self.register = register
|
||||||
|
self.height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public struct RoomContainer: Codable, Equatable, Sendable {
|
public struct RoomContainer: Codable, Equatable, Sendable {
|
||||||
|
|
||||||
public let registerID: String
|
public let registerID: String
|
||||||
@@ -17,6 +32,8 @@ public enum DuctSizing {
|
|||||||
public let finalSize: Int
|
public let finalSize: Int
|
||||||
public let velocity: Int
|
public let velocity: Int
|
||||||
public let flexSize: Int
|
public let flexSize: Int
|
||||||
|
public let rectangularSize: RectangularDuct?
|
||||||
|
public let rectangularWidth: Int?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
registerID: String,
|
registerID: String,
|
||||||
@@ -30,7 +47,9 @@ public enum DuctSizing {
|
|||||||
roundSize: Double,
|
roundSize: Double,
|
||||||
finalSize: Int,
|
finalSize: Int,
|
||||||
velocity: Int,
|
velocity: Int,
|
||||||
flexSize: Int
|
flexSize: Int,
|
||||||
|
rectangularSize: RectangularDuct? = nil,
|
||||||
|
rectangularWidth: Int? = nil
|
||||||
) {
|
) {
|
||||||
self.registerID = registerID
|
self.registerID = registerID
|
||||||
self.roomID = roomID
|
self.roomID = roomID
|
||||||
@@ -44,6 +63,8 @@ public enum DuctSizing {
|
|||||||
self.finalSize = finalSize
|
self.finalSize = finalSize
|
||||||
self.velocity = velocity
|
self.velocity = velocity
|
||||||
self.flexSize = flexSize
|
self.flexSize = flexSize
|
||||||
|
self.rectangularSize = rectangularSize
|
||||||
|
self.rectangularWidth = rectangularWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ public struct Room: Codable, Equatable, Identifiable, Sendable {
|
|||||||
public let coolingTotal: Double
|
public let coolingTotal: Double
|
||||||
public let coolingSensible: Double?
|
public let coolingSensible: Double?
|
||||||
public let registerCount: Int
|
public let registerCount: Int
|
||||||
|
public let rectangularSizes: [DuctSizing.RectangularDuct]?
|
||||||
public let createdAt: Date
|
public let createdAt: Date
|
||||||
public let updatedAt: Date
|
public let updatedAt: Date
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ public struct Room: Codable, Equatable, Identifiable, Sendable {
|
|||||||
coolingTotal: Double,
|
coolingTotal: Double,
|
||||||
coolingSensible: Double? = nil,
|
coolingSensible: Double? = nil,
|
||||||
registerCount: Int = 1,
|
registerCount: Int = 1,
|
||||||
|
rectangularSizes: [DuctSizing.RectangularDuct]? = nil,
|
||||||
createdAt: Date,
|
createdAt: Date,
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
) {
|
) {
|
||||||
@@ -30,6 +32,7 @@ public struct Room: Codable, Equatable, Identifiable, Sendable {
|
|||||||
self.coolingTotal = coolingTotal
|
self.coolingTotal = coolingTotal
|
||||||
self.coolingSensible = coolingSensible
|
self.coolingSensible = coolingSensible
|
||||||
self.registerCount = registerCount
|
self.registerCount = registerCount
|
||||||
|
self.rectangularSizes = rectangularSizes
|
||||||
self.createdAt = createdAt
|
self.createdAt = createdAt
|
||||||
self.updatedAt = updatedAt
|
self.updatedAt = updatedAt
|
||||||
}
|
}
|
||||||
@@ -68,6 +71,7 @@ extension Room {
|
|||||||
public let coolingTotal: Double?
|
public let coolingTotal: Double?
|
||||||
public let coolingSensible: Double?
|
public let coolingSensible: Double?
|
||||||
public let registerCount: Int?
|
public let registerCount: Int?
|
||||||
|
public let rectangularSizes: [DuctSizing.RectangularDuct]?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
name: String? = nil,
|
name: String? = nil,
|
||||||
@@ -81,6 +85,18 @@ extension Room {
|
|||||||
self.coolingTotal = coolingTotal
|
self.coolingTotal = coolingTotal
|
||||||
self.coolingSensible = coolingSensible
|
self.coolingSensible = coolingSensible
|
||||||
self.registerCount = registerCount
|
self.registerCount = registerCount
|
||||||
|
self.rectangularSizes = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(
|
||||||
|
rectangularSizes: [DuctSizing.RectangularDuct]
|
||||||
|
) {
|
||||||
|
self.name = nil
|
||||||
|
self.heatingLoad = nil
|
||||||
|
self.coolingTotal = nil
|
||||||
|
self.coolingSensible = nil
|
||||||
|
self.registerCount = nil
|
||||||
|
self.rectangularSizes = rectangularSizes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -677,6 +677,7 @@ extension SiteRoute.View.ProjectRoute {
|
|||||||
|
|
||||||
public enum DuctSizingRoute: Equatable, Sendable {
|
public enum DuctSizingRoute: Equatable, Sendable {
|
||||||
case index
|
case index
|
||||||
|
case roomRectangularForm(Room.ID, RoomRectangularForm)
|
||||||
|
|
||||||
static let rootPath = "duct-sizing"
|
static let rootPath = "duct-sizing"
|
||||||
|
|
||||||
@@ -685,6 +686,26 @@ extension SiteRoute.View.ProjectRoute {
|
|||||||
Path { rootPath }
|
Path { rootPath }
|
||||||
Method.get
|
Method.get
|
||||||
}
|
}
|
||||||
|
Route(.case(Self.roomRectangularForm)) {
|
||||||
|
Path {
|
||||||
|
rootPath
|
||||||
|
"room"
|
||||||
|
Room.ID.parser()
|
||||||
|
}
|
||||||
|
Method.post
|
||||||
|
Body {
|
||||||
|
FormData {
|
||||||
|
Field("register") { Int.parser() }
|
||||||
|
Field("height") { Int.parser() }
|
||||||
|
}
|
||||||
|
.map(.memberwise(RoomRectangularForm.init))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct RoomRectangularForm: Equatable, Sendable {
|
||||||
|
public let register: Int
|
||||||
|
public let height: Int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ extension ManualDClient {
|
|||||||
logger: logger
|
logger: logger
|
||||||
)
|
)
|
||||||
|
|
||||||
logger?.debug("Rooms: \(ductRooms)")
|
// logger?.debug("Rooms: \(ductRooms)")
|
||||||
|
|
||||||
return ductRooms
|
return ductRooms
|
||||||
|
|
||||||
|
|||||||
@@ -342,11 +342,31 @@ extension SiteRoute.View.ProjectRoute.DuctSizingRoute {
|
|||||||
func renderView(on request: ViewController.Request, projectID: Project.ID) async throws
|
func renderView(on request: ViewController.Request, projectID: Project.ID) async throws
|
||||||
-> AnySendableHTML
|
-> AnySendableHTML
|
||||||
{
|
{
|
||||||
|
@Dependency(\.database) var database
|
||||||
|
@Dependency(\.manualD) var manualD
|
||||||
|
|
||||||
switch self {
|
switch self {
|
||||||
case .index:
|
case .index:
|
||||||
return request.view {
|
return request.view {
|
||||||
ProjectView(projectID: projectID, activeTab: .ductSizing, logger: request.logger)
|
ProjectView(projectID: projectID, activeTab: .ductSizing, logger: request.logger)
|
||||||
}
|
}
|
||||||
|
case .roomRectangularForm(let roomID, let form):
|
||||||
|
let _ = try await database.rooms.update(
|
||||||
|
roomID,
|
||||||
|
.init(rectangularSizes: [.init(register: form.register, height: form.height)])
|
||||||
|
)
|
||||||
|
// request.logger.debug("Got room rectangular form: \(roomID)")
|
||||||
|
//
|
||||||
|
// let containers = try await manualD.calculate(
|
||||||
|
// rooms: [room],
|
||||||
|
// designFrictionRateResult: database.designFrictionRate(projectID: projectID),
|
||||||
|
// projectSHR: database.projects.getSensibleHeatRatio(projectID)
|
||||||
|
// )
|
||||||
|
// request.logger.debug("Room Containers: \(containers)")
|
||||||
|
// let container = containers.first(where: { $0.roomName == "\(room.name)-\(form.register)" })!
|
||||||
|
// request.logger.debug("Room Container: \(container)")
|
||||||
|
// return DuctSizingView.RoomRow(projectID: projectID, room: container)
|
||||||
|
return ProjectView(projectID: projectID, activeTab: .ductSizing, logger: request.logger)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import ElementaryHTMX
|
|||||||
import ManualDCore
|
import ManualDCore
|
||||||
import Styleguide
|
import Styleguide
|
||||||
|
|
||||||
|
// FIX: The value field is sometimes wonky as far as what values it accepts.
|
||||||
|
|
||||||
struct ComponentLossForm: HTML, Sendable {
|
struct ComponentLossForm: HTML, Sendable {
|
||||||
|
|
||||||
static func id(_ componentLoss: ComponentPressureLoss? = nil) -> String {
|
static func id(_ componentLoss: ComponentPressureLoss? = nil) -> String {
|
||||||
@@ -49,7 +51,7 @@ struct ComponentLossForm: HTML, Sendable {
|
|||||||
label(.for("value")) { "Value" }
|
label(.for("value")) { "Value" }
|
||||||
Input(id: "value", placeholder: "Pressure loss")
|
Input(id: "value", placeholder: "Pressure loss")
|
||||||
.attributes(
|
.attributes(
|
||||||
.type(.number), .min("0.03"), .max("1.0"), .step("0.1"), .required,
|
.type(.number), .min("0.03"), .max("1.0"), .step("0.01"), .required,
|
||||||
.value(componentLoss?.value)
|
.value(componentLoss?.value)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,27 @@ import Styleguide
|
|||||||
|
|
||||||
struct DuctSizingView: HTML, Sendable {
|
struct DuctSizingView: HTML, Sendable {
|
||||||
|
|
||||||
|
let projectID: Project.ID
|
||||||
let rooms: [DuctSizing.RoomContainer]
|
let rooms: [DuctSizing.RoomContainer]
|
||||||
|
|
||||||
var body: some HTML {
|
var body: some HTML {
|
||||||
div {
|
div {
|
||||||
h1(.class("text-2xl py-4")) { "Duct Sizes" }
|
h1(.class("text-2xl py-4")) { "Duct Sizes" }
|
||||||
|
if rooms.count == 0 {
|
||||||
|
p(.class("text-error italic")) {
|
||||||
|
"Must complete all the previous sections to display duct sizing calculations."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RoomsTable(projectID: projectID, rooms: rooms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RoomsTable: HTML, Sendable {
|
||||||
|
let projectID: Project.ID
|
||||||
|
let rooms: [DuctSizing.RoomContainer]
|
||||||
|
|
||||||
|
var body: some HTML<HTMLTag.div> {
|
||||||
div(.class("overflow-x-auto")) {
|
div(.class("overflow-x-auto")) {
|
||||||
table(.class("table table-zebra")) {
|
table(.class("table table-zebra")) {
|
||||||
thead {
|
thead {
|
||||||
@@ -27,12 +42,14 @@ struct DuctSizingView: HTML, Sendable {
|
|||||||
th(.class("hidden xl:table-cell")) { "Round Size" }
|
th(.class("hidden xl:table-cell")) { "Round Size" }
|
||||||
th { "Velocity" }
|
th { "Velocity" }
|
||||||
th { "Final Size" }
|
th { "Final Size" }
|
||||||
|
th { "Height" }
|
||||||
|
th { "Width" }
|
||||||
th { "Flex Size" }
|
th { "Flex Size" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tbody {
|
tbody {
|
||||||
for room in rooms {
|
for room in rooms {
|
||||||
RoomRow(room: room)
|
RoomRow(projectID: projectID, room: room)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,10 +58,19 @@ struct DuctSizingView: HTML, Sendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RoomRow: HTML, Sendable {
|
struct RoomRow: HTML, Sendable {
|
||||||
|
let projectID: Project.ID
|
||||||
let room: DuctSizing.RoomContainer
|
let room: DuctSizing.RoomContainer
|
||||||
|
|
||||||
|
var route: String {
|
||||||
|
SiteRoute.View.router.path(
|
||||||
|
for: .project(.detail(projectID, .ductSizing(.index)))
|
||||||
|
)
|
||||||
|
.appendingPath("room")
|
||||||
|
.appendingPath(room.roomID)
|
||||||
|
}
|
||||||
|
|
||||||
var body: some HTML<HTMLTag.tr> {
|
var body: some HTML<HTMLTag.tr> {
|
||||||
tr(.class("text-lg")) {
|
tr(.class("text-lg"), .id(room.roomID.idString)) {
|
||||||
td { room.registerID }
|
td { room.registerID }
|
||||||
td { room.roomName }
|
td { room.roomName }
|
||||||
td { Number(room.heatingLoad, digits: 0) }
|
td { Number(room.heatingLoad, digits: 0) }
|
||||||
@@ -62,6 +88,32 @@ struct DuctSizingView: HTML, Sendable {
|
|||||||
Number(room.finalSize)
|
Number(room.finalSize)
|
||||||
.attributes(.class("badge badge-outline badge-secondary text-xl font-bold"))
|
.attributes(.class("badge badge-outline badge-secondary text-xl font-bold"))
|
||||||
}
|
}
|
||||||
|
td {
|
||||||
|
form(
|
||||||
|
.hx.post(route),
|
||||||
|
.hx.target("body"),
|
||||||
|
.hx.swap(.outerHTML)
|
||||||
|
// .hx.trigger(
|
||||||
|
// .event(.change).from("#rectangularSize_\(room.roomID.idString)")
|
||||||
|
// )
|
||||||
|
) {
|
||||||
|
input(.class("hidden"), .name("register"), .value("\(room.roomName.last!)"))
|
||||||
|
Row {
|
||||||
|
Input(
|
||||||
|
id: "height",
|
||||||
|
name: "height",
|
||||||
|
placeholder: "Height"
|
||||||
|
)
|
||||||
|
.attributes(.type(.number), .min("0"), .value(room.rectangularSize?.height))
|
||||||
|
SubmitButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
if let width = room.rectangularWidth {
|
||||||
|
Number(width)
|
||||||
|
}
|
||||||
|
}
|
||||||
td {
|
td {
|
||||||
Number(room.flexSize)
|
Number(room.flexSize)
|
||||||
.attributes(.class("badge badge-outline badge-primary text-xl font-bold"))
|
.attributes(.class("badge badge-outline badge-primary text-xl font-bold"))
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import Elementary
|
|||||||
import ManualDCore
|
import ManualDCore
|
||||||
import Styleguide
|
import Styleguide
|
||||||
|
|
||||||
|
// FIX: Need to update available static, etc. when equipment info is submitted.
|
||||||
|
|
||||||
struct FrictionRateView: HTML, Sendable {
|
struct FrictionRateView: HTML, Sendable {
|
||||||
|
|
||||||
let equipmentInfo: EquipmentInfo?
|
let equipmentInfo: EquipmentInfo?
|
||||||
@@ -46,8 +48,8 @@ struct FrictionRateView: HTML, Sendable {
|
|||||||
div(.class("p-4 space-y-6")) {
|
div(.class("p-4 space-y-6")) {
|
||||||
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
|
h1(.class("text-4xl font-bold pb-6")) { "Friction Rate" }
|
||||||
div(.class("flex space-x-4")) {
|
div(.class("flex space-x-4")) {
|
||||||
Label("Available Static Pressure")
|
|
||||||
if let availableStaticPressure {
|
if let availableStaticPressure {
|
||||||
|
Label("Available Static Pressure")
|
||||||
Number(availableStaticPressure, digits: 2)
|
Number(availableStaticPressure, digits: 2)
|
||||||
.attributes(.class("badge badge-lg badge-outline font-bold ms-4"))
|
.attributes(.class("badge badge-lg badge-outline font-bold ms-4"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ struct ProjectView: HTML, Sendable {
|
|||||||
)
|
)
|
||||||
case .ductSizing:
|
case .ductSizing:
|
||||||
try await DuctSizingView(
|
try await DuctSizingView(
|
||||||
|
projectID: projectID,
|
||||||
rooms: manualD.calculate(
|
rooms: manualD.calculate(
|
||||||
rooms: database.rooms.fetch(projectID),
|
rooms: database.rooms.fetch(projectID),
|
||||||
designFrictionRateResult: database.designFrictionRate(projectID: projectID),
|
designFrictionRateResult: database.designFrictionRate(projectID: projectID),
|
||||||
|
|||||||
Reference in New Issue
Block a user