Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add climate_setting_schedules/get and climate_setting_schedules/delete #55

Merged
merged 8 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions public/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3345,6 +3345,135 @@
"operationId": "thermostatsClimateSettingSchedulesCreatePost"
}
},
"/thermostats/climate_setting_schedules/delete": {
"post": {
"summary": "/thermostats/climate_setting_schedules/delete",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": { "ok": { "type": "boolean" } },
"required": ["ok"]
}
}
}
},
"400": { "description": "Bad Request" },
"401": { "description": "Unauthorized" }
},
"security": [{ "cst_ak_pk": [] }],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"climate_setting_schedule_id": { "type": "string" },
"sync": { "default": false, "type": "boolean" }
},
"required": ["climate_setting_schedule_id"]
}
}
}
},
"parameters": [
{
"name": "climate_setting_schedule_id",
"in": "query",
"schema": { "type": "string" },
"required": true
},
{
"name": "sync",
"in": "query",
"schema": { "default": false, "type": "boolean" },
"required": false
}
],
"tags": [],
"operationId": "thermostatsClimateSettingSchedulesDeletePost"
}
},
"/thermostats/climate_setting_schedules/get": {
"post": {
"summary": "/thermostats/climate_setting_schedules/get",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"climate_setting_schedule": {
"type": "object",
"properties": {
"climate_setting_schedule_id": {
"type": "string",
"format": "uuid"
},
"schedule_type": {
"type": "string",
"enum": ["time_bound"]
},
"device_id": { "type": "string" },
"name": { "type": "string" },
"schedule_starts_at": { "type": "string" },
"schedule_ends_at": { "type": "string" },
"created_at": { "type": "string" },
"automatic_heating_enabled": { "type": "boolean" },
"automatic_cooling_enabled": { "type": "boolean" },
"hvac_mode_setting": {
"type": "string",
"enum": ["off", "heat", "cool", "heatcool"]
},
"cooling_set_point_celsius": { "type": "number" },
"heating_set_point_celsius": { "type": "number" },
"cooling_set_point_fahrenheit": { "type": "number" },
"heating_set_point_fahrenheit": { "type": "number" },
"manual_override_allowed": { "type": "boolean" }
},
"required": [
"climate_setting_schedule_id",
"schedule_type",
"device_id",
"schedule_starts_at",
"schedule_ends_at",
"created_at"
]
},
"ok": { "type": "boolean" }
},
"required": ["climate_setting_schedule", "ok"]
}
}
}
},
"400": { "description": "Bad Request" },
"401": { "description": "Unauthorized" }
},
"security": [{ "cst_ak_pk": [] }],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"climate_setting_schedule_id": { "type": "string" },
"device_id": { "type": "string" }
},
"required": ["climate_setting_schedule_id"]
}
}
}
},
"tags": [],
"operationId": "thermostatsClimateSettingSchedulesGetPost"
}
},
"/thermostats/climate_setting_schedules/list": {
"post": {
"summary": "/thermostats/climate_setting_schedules/list",
Expand Down
5 changes: 5 additions & 0 deletions src/lib/database/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export interface DatabaseMethods {
original_access_code_id: string
pulled_backup_access_code_id: string
}) => void
findClimateSettingSchedule: (params: {
climate_setting_schedule_id: string
device_id?: string
}) => ClimateSettingSchedule | undefined
addClimateSettingSchedule: (
params: {
workspace_id: string
Expand All @@ -115,6 +119,7 @@ export interface DatabaseMethods {
name: string
} & Partial<ClimateSetting>
) => ClimateSettingSchedule
deleteClimateSettingSchedule: (params: ClimateSettingSchedule) => void

update: (t?: number) => void
}
Expand Down
39 changes: 39 additions & 0 deletions src/lib/database/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,44 @@ const initializer = immer<Database>((set, get) => ({
return new_climate_setting_schedule
},

findClimateSettingSchedule(params) {
return get().climate_setting_schedules.find((climate_setting_schedule) => {
const is_target_id =
climate_setting_schedule.climate_setting_schedule_id ===
params.climate_setting_schedule_id
const is_target_device =
climate_setting_schedule.device_id === params.device_id

return is_target_id || is_target_device
})
},

deleteClimateSettingSchedule(params) {
const target = get().climate_setting_schedules.find(
(climate_setting_schedule) =>
climate_setting_schedule.climate_setting_schedule_id ===
params.climate_setting_schedule_id
)
if (target == null) {
throw new Error(
"Could not find climate_setting_schedule with climate_setting_schedule_id"
)
}

set({
climate_setting_schedules: [
...get().climate_setting_schedules.filter(
(climate_setting_schedule) => {
const is_target =
climate_setting_schedule.climate_setting_schedule_id ===
target.climate_setting_schedule_id

return !is_target
}
),
],
})
},

update() {},
}))
34 changes: 34 additions & 0 deletions src/pages/api/thermostats/climate_setting_schedules/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { NotFoundException } from "nextlove"
import { z } from "zod"

import { withRouteSpec } from "lib/middleware/with-route-spec.ts"

const json_body = z.object({
climate_setting_schedule_id: z.string(),
sync: z.boolean().default(false),
})

export default withRouteSpec({
auth: "cst_ak_pk",
methods: ["POST", "DELETE"],
jsonBody: json_body,
jsonResponse: z.object({}),
} as const)(async (req, res) => {
const { climate_setting_schedule_id } = req.body

const climate_setting_schedule = req.db.findClimateSettingSchedule({
climate_setting_schedule_id,
})

if (climate_setting_schedule == null) {
throw new NotFoundException({
type: "climate_setting_schedule_not_found",
message: `Could not find an climate_setting_schedule with climate_setting_schedule_id`,
data: { climate_setting_schedule_id },
})
}

req.db.deleteClimateSettingSchedule(climate_setting_schedule)

res.status(200).json({})
})
34 changes: 34 additions & 0 deletions src/pages/api/thermostats/climate_setting_schedules/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { NotFoundException } from "nextlove"
import { z } from "zod"

import { climate_setting_schedule } from "lib/zod/index.ts"

import { withRouteSpec } from "lib/middleware/with-route-spec.ts"

export default withRouteSpec({
auth: "cst_ak_pk",
methods: ["GET", "POST"],
commonParams: z.object({
climate_setting_schedule_id: z.string(),
device_id: z.string().optional(),
}),
jsonResponse: z.object({
climate_setting_schedule,
}),
} as const)(async (req, res) => {
const { device_id, climate_setting_schedule_id } = req.commonParams

const climate_setting_schedule = req.db.findClimateSettingSchedule({
climate_setting_schedule_id,
device_id,
})

if (climate_setting_schedule == null) {
throw new NotFoundException({
type: "climate_setting_schedule_not_found",
message: `Could not find an climate_setting_schedule with climate_setting_schedule_id`,
data: { climate_setting_schedule_id },
})
}
res.status(200).json({ climate_setting_schedule })
})
42 changes: 42 additions & 0 deletions src/route-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,48 @@ export type Routes = {
}
}
}
"/thermostats/climate_setting_schedules/delete": {
route: "/thermostats/climate_setting_schedules/delete"
method: "POST" | "DELETE"
queryParams: {}
jsonBody: {
climate_setting_schedule_id: string
sync?: boolean
}
commonParams: {}
formData: {}
jsonResponse: {}
}
"/thermostats/climate_setting_schedules/get": {
route: "/thermostats/climate_setting_schedules/get"
method: "GET" | "POST"
queryParams: {}
jsonBody: {}
commonParams: {
climate_setting_schedule_id: string
device_id?: string | undefined
}
formData: {}
jsonResponse: {
climate_setting_schedule: {
climate_setting_schedule_id: string
schedule_type: "time_bound"
device_id: string
name?: string | undefined
schedule_starts_at: string
schedule_ends_at: string
created_at: string
automatic_heating_enabled?: boolean | undefined
automatic_cooling_enabled?: boolean | undefined
hvac_mode_setting?: ("off" | "heat" | "cool" | "heatcool") | undefined
cooling_set_point_celsius?: (number | undefined) | undefined
heating_set_point_celsius?: (number | undefined) | undefined
cooling_set_point_fahrenheit?: (number | undefined) | undefined
heating_set_point_fahrenheit?: (number | undefined) | undefined
manual_override_allowed?: boolean | undefined
}
}
}
"/thermostats/climate_setting_schedules/list": {
route: "/thermostats/climate_setting_schedules/list"
method: "GET" | "POST"
Expand Down
18 changes: 18 additions & 0 deletions test/api/thermostats/climate_setting_schedules/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,22 @@ test("POST /thermostats/climate_setting_schedules/create", async (t: ExecutionCo
t.true(schedule_from_list?.automatic_cooling_enabled)
t.is(schedule_from_list?.heating_set_point_fahrenheit, 40)
t.is(schedule_from_list?.cooling_set_point_fahrenheit, 80)

const {
data: { climate_setting_schedule: schedule_from_get },
} = await axios.get("/thermostats/climate_setting_schedules/get", {
params: {
climate_setting_schedule_id:
climate_setting_schedule.climate_setting_schedule_id,
},
headers: {
Authorization: `Bearer ${seed.ws2.cst}`,
},
})

t.true(schedule_from_get?.manual_override_allowed)
t.true(schedule_from_get?.automatic_heating_enabled)
t.true(schedule_from_get?.automatic_cooling_enabled)
t.is(schedule_from_get?.heating_set_point_fahrenheit, 40)
t.is(schedule_from_get?.cooling_set_point_fahrenheit, 80)
})
Loading