diff --git a/docs/api/thermostats/README.md b/docs/api/thermostats/README.md
index 66d5e32cc..7b588df9a 100644
--- a/docs/api/thermostats/README.md
+++ b/docs/api/thermostats/README.md
@@ -41,3 +41,479 @@ Sets a [temperature threshold](../../capability-guides/thermostats/setting-and-m
### [`/thermostats/update_climate_preset`](./update_climate_preset.md)
Updates a specified [climate preset](../../capability-guides/thermostats/creating-and-managing-climate-presets/README.md) for a specified [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+---
+
+## Events
+
+### `thermostat.climate_preset_activated`
+
+A thermostat [climate preset](../../capability-guides/thermostats/creating-and-managing-climate-presets/README.md) was activated.
+
+
+
+climate_preset_key Format: String
+
+Key of the [climate preset](../../capability-guides/thermostats/creating-and-managing-climate-presets/README.md) that was activated.
+
+
+
+connected_account_id Format: UUID
+
+ID of the [connected account](../../core-concepts/connected-accounts/README.md).
+
+
+
+created_at Format: Datetime
+
+Date and time at which the event was created.
+
+
+
+device_id Format: UUID
+
+ID of the device.
+
+
+
+event_id Format: UUID
+
+ID of the event.
+
+
+
+event_type Format: Enum
+
+Value: `thermostat.climate_preset_activated`
+
+
+
+is_fallback_climate_preset Format: Boolean
+
+Indicates whether the [climate preset](../../capability-guides/thermostats/creating-and-managing-climate-presets/README.md) that was activated is the [fallback climate preset](../../capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset.md) for the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+occurred_at Format: Datetime
+
+Date and time at which the event occurred.
+
+
+
+thermostat_schedule_id Format: UUID
+
+ID of the [thermostat schedule](../../capability-guides/thermostats/creating-and-managing-thermostat-schedules.md) that prompted the [climate preset](../../capability-guides/thermostats/creating-and-managing-climate-presets/README.md) to be activated.
+
+
+
+workspace_id Format: UUID
+
+ID of the [workspace](../../core-concepts/workspaces/README.md).
+
+---
+
+### `thermostat.manually_adjusted`
+
+A [thermostat](https://docs.seam.co/latest/capability-guides/thermostats) was adjusted manually.
+
+
+
+connected_account_id Format: UUID
+
+ID of the [connected account](../../core-concepts/connected-accounts/README.md).
+
+
+
+cooling_set_point_celsius Format: Number
+
+Temperature to which the thermostat should cool (in °C). See also [Set Points](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+cooling_set_point_fahrenheit Format: Number
+
+Temperature to which the thermostat should cool (in °F). See also [Set Points](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+created_at Format: Datetime
+
+Date and time at which the event was created.
+
+
+
+device_id Format: UUID
+
+ID of the device.
+
+
+
+event_id Format: UUID
+
+ID of the event.
+
+
+
+event_type Format: Enum
+
+Value: `thermostat.manually_adjusted`
+
+
+
+fan_mode_setting Format: Enum
+
+Desired [fan mode setting](https://docs.seam.co/latest/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`.
+
+Possible enum values:
+- `auto`
+- `on`
+- `circulate`
+
+
+
+heating_set_point_celsius Format: Number
+
+Temperature to which the thermostat should heat (in °C). See also [Set Points](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+heating_set_point_fahrenheit Format: Number
+
+Temperature to which the thermostat should heat (in °F). See also [Set Points](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+hvac_mode_setting Format: Enum
+
+Desired [HVAC mode](../../capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode.md) setting, such as `heat`, `cool`, `heat_cool`, or `off`.
+
+Possible enum values:
+- `off`
+- `heat`
+- `cool`
+- `heat_cool`
+
+
+
+method Format: Enum
+
+Method used to adjust the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats) manually. `seam` indicates that the Seam API, Seam CLI, or Seam Console was used to adjust the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+Possible enum values:
+- `seam`
+- `external`
+
+
+
+occurred_at Format: Datetime
+
+Date and time at which the event occurred.
+
+
+
+workspace_id Format: UUID
+
+ID of the [workspace](../../core-concepts/workspaces/README.md).
+
+---
+
+### `thermostat.temperature_threshold_exceeded`
+
+A [thermostat's](https://docs.seam.co/latest/capability-guides/thermostats) temperature reading exceeded the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+connected_account_id Format: UUID
+
+ID of the [connected account](../../core-concepts/connected-accounts/README.md).
+
+
+
+created_at Format: Datetime
+
+Date and time at which the event was created.
+
+
+
+device_id Format: UUID
+
+ID of the device.
+
+
+
+event_id Format: UUID
+
+ID of the event.
+
+
+
+event_type Format: Enum
+
+Value: `thermostat.temperature_threshold_exceeded`
+
+
+
+lower_limit_celsius Format: Number
+
+Lower temperature limit, in °C, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+lower_limit_fahrenheit Format: Number
+
+Lower temperature limit, in °F, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+occurred_at Format: Datetime
+
+Date and time at which the event occurred.
+
+
+
+temperature_celsius Format: Number
+
+Temperature, in °C, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+temperature_fahrenheit Format: Number
+
+Temperature, in °F, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+upper_limit_celsius Format: Number
+
+Upper temperature limit, in °C, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+upper_limit_fahrenheit Format: Number
+
+Upper temperature limit, in °F, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+workspace_id Format: UUID
+
+ID of the [workspace](../../core-concepts/workspaces/README.md).
+
+---
+
+### `thermostat.temperature_threshold_no_longer_exceeded`
+
+A [thermostat's](https://docs.seam.co/latest/capability-guides/thermostats) temperature reading no longer exceeds the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+connected_account_id Format: UUID
+
+ID of the [connected account](../../core-concepts/connected-accounts/README.md).
+
+
+
+created_at Format: Datetime
+
+Date and time at which the event was created.
+
+
+
+device_id Format: UUID
+
+ID of the device.
+
+
+
+event_id Format: UUID
+
+ID of the event.
+
+
+
+event_type Format: Enum
+
+Value: `thermostat.temperature_threshold_no_longer_exceeded`
+
+
+
+lower_limit_celsius Format: Number
+
+Lower temperature limit, in °C, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+lower_limit_fahrenheit Format: Number
+
+Lower temperature limit, in °F, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+occurred_at Format: Datetime
+
+Date and time at which the event occurred.
+
+
+
+temperature_celsius Format: Number
+
+Temperature, in °C, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+temperature_fahrenheit Format: Number
+
+Temperature, in °F, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+upper_limit_celsius Format: Number
+
+Upper temperature limit, in °C, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+upper_limit_fahrenheit Format: Number
+
+Upper temperature limit, in °F, defined by the set [threshold](../../capability-guides/thermostats/setting-and-monitoring-temperature-thresholds.md).
+
+
+
+workspace_id Format: UUID
+
+ID of the [workspace](../../core-concepts/workspaces/README.md).
+
+---
+
+### `thermostat.temperature_reached_set_point`
+
+A [thermostat's](https://docs.seam.co/latest/capability-guides/thermostats) temperature reading is within 1 °C of the configured cooling or heating [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+connected_account_id Format: UUID
+
+ID of the [connected account](../../core-concepts/connected-accounts/README.md).
+
+
+
+created_at Format: Datetime
+
+Date and time at which the event was created.
+
+
+
+desired_temperature_celsius Format: Number
+
+Desired temperature, in °C, defined by the [thermostat's](https://docs.seam.co/latest/capability-guides/thermostats) cooling or heating [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+desired_temperature_fahrenheit Format: Number
+
+Desired temperature, in °F, defined by the [thermostat's](https://docs.seam.co/latest/capability-guides/thermostats) cooling or heating [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points.md).
+
+
+
+device_id Format: UUID
+
+ID of the device.
+
+
+
+event_id Format: UUID
+
+ID of the event.
+
+
+
+event_type Format: Enum
+
+Value: `thermostat.temperature_reached_set_point`
+
+
+
+occurred_at Format: Datetime
+
+Date and time at which the event occurred.
+
+
+
+temperature_celsius Format: Number
+
+Temperature, in °C, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+temperature_fahrenheit Format: Number
+
+Temperature, in °F, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+workspace_id Format: UUID
+
+ID of the [workspace](../../core-concepts/workspaces/README.md).
+
+---
+
+### `thermostat.temperature_changed`
+
+A [thermostat's](https://docs.seam.co/latest/capability-guides/thermostats) reported temperature changed by at least 1 °C.
+
+
+
+connected_account_id Format: UUID
+
+ID of the [connected account](../../core-concepts/connected-accounts/README.md).
+
+
+
+created_at Format: Datetime
+
+Date and time at which the event was created.
+
+
+
+device_id Format: UUID
+
+ID of the device.
+
+
+
+event_id Format: UUID
+
+ID of the event.
+
+
+
+event_type Format: Enum
+
+Value: `thermostat.temperature_changed`
+
+
+
+occurred_at Format: Datetime
+
+Date and time at which the event occurred.
+
+
+
+temperature_celsius Format: Number
+
+Temperature, in °C, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+temperature_fahrenheit Format: Number
+
+Temperature, in °F, reported by the [thermostat](https://docs.seam.co/latest/capability-guides/thermostats).
+
+
+
+workspace_id Format: UUID
+
+ID of the [workspace](../../core-concepts/workspaces/README.md).
+
+---
+
diff --git a/src/lib/layout/api-route.ts b/src/lib/layout/api-route.ts
index 6fcf63398..fd51d64cd 100644
--- a/src/lib/layout/api-route.ts
+++ b/src/lib/layout/api-route.ts
@@ -85,13 +85,17 @@ export function setApiRouteLayoutContext(
blueprint: Blueprint,
pathMetadata: PathMetadata,
): void {
- file.events = []
const metadata = pathMetadata[route.path]
if (metadata == null) {
throw new Error(`Missing path metadata for ${route.path}`)
}
+
file.title = metadata.title
file.path = route.path
+
+ const eventsByRoutePath = groupEventsByRoutePath(blueprint.events)
+ file.events = eventsByRoutePath.get(route.path) ?? []
+
file.endpoints = route.endpoints
.filter(
({ isUndocumented, title }) => !isUndocumented && title.length !== 0,
@@ -112,27 +116,6 @@ export function setApiRouteLayoutContext(
)
}
- const resourceEvents: ApiRouteEvent[] = []
- for (const event of blueprint.events) {
- if (
- event.targetResourceType == null ||
- event.targetResourceType !== resourceType
- ) {
- continue
- }
-
- const routeEvent: ApiRouteEvent = {
- name: event.eventType,
- description: event.description,
- properties: event.properties
- .filter(({ isUndocumented }) => !isUndocumented)
- .map(mapBlueprintPropertyToRouteProperty),
- }
-
- resourceEvents.push(routeEvent)
- file.events.push(routeEvent)
- }
-
const warningsProp = resource.properties.find((p) => p.name === 'warnings')
const errorsProp = resource.properties.find((p) => p.name === 'errors')
const resourceWarnings =
@@ -155,12 +138,35 @@ export function setApiRouteLayoutContext(
properties,
errors: resourceErrors,
warnings: resourceWarnings,
- events: resourceEvents,
+ events: eventsByRoutePath.get(resource.routePath) ?? [],
resourceSamples: resource.resourceSamples.map(mapResourceSample),
})
}
}
+const groupEventsByRoutePath = (
+ events: Blueprint['events'],
+): Map => {
+ const eventsByRoutePath = new Map()
+
+ for (const event of events) {
+ if (event.routePath == null) continue
+
+ const routeEvents = eventsByRoutePath.get(event.routePath) ?? []
+ routeEvents.push({
+ name: event.eventType,
+ description: event.description,
+ properties: event.properties
+ .filter(({ isUndocumented }) => !isUndocumented)
+ .map(mapBlueprintPropertyToRouteProperty),
+ })
+
+ eventsByRoutePath.set(event.routePath, routeEvents)
+ }
+
+ return eventsByRoutePath
+}
+
const getFirstParagraph = (text: string): string =>
text.split('\n\n').at(0) ?? text