UNPKG

rhombus-node-mcp

Version:
375 lines (374 loc) 18.2 kB
import { z } from "zod"; import { ISOTimestampFormatDescription } from "../utils/timestampInput.js"; import { ComponentEventEnumType } from "./schema.js"; import { CameraFootageEvent } from "../api/events-tool-api.js"; import { TempUnit } from "../utils/temp.js"; export var EventsToolRequestType; (function (EventsToolRequestType) { EventsToolRequestType["ACCESS_CONTROL"] = "access-control"; EventsToolRequestType["BRIVO_ACCESS_CONTROL"] = "brivo-access-control"; EventsToolRequestType["ENVIRONMENTAL_GATEWAY"] = "environmental-gateway"; EventsToolRequestType["CLIMATE_SENSOR"] = "climate-sensor"; EventsToolRequestType["COMPONENT_EVENTS"] = "component-events"; EventsToolRequestType["CAMERA"] = "camera"; EventsToolRequestType["BUTTON_PRESS"] = "button-press"; EventsToolRequestType["OCCUPANCY"] = "occupancy"; EventsToolRequestType["PROXIMITY"] = "proximity"; EventsToolRequestType["DOORBELL"] = "doorbell"; })(EventsToolRequestType || (EventsToolRequestType = {})); export const TOOL_ARGS = { eventType: z .nativeEnum(EventsToolRequestType) .describe("The type of events to retrieve. " + "access-control: Access control events like unlocks, badge ins, credentials, arrivals. " + "brivo-access-control: Badge/credential events from Brivo-integrated doors. Does not require door UUIDs — automatically looks up which doors are configured via the Brivo integration. " + "environmental-gateway: Environmental gateway events with sensor readings and derived values. " + "climate-sensor: Climate sensor events with temperature, humidity, air quality readings. " + "component-events: All types of component events for a location (most flexible option). " + "camera: Footage seekpoints for one camera—all timeline activity types that camera recorded (human motion, vehicle motion, etc., depending on device/analytics). For org LPR saved vehicles, labels, and plate search APIs, use lpr-tool. " + "button-press: Button press events from button sensors. " + "occupancy: Occupancy sensor events with people count. " + "proximity: Proximity tag events with RSSI readings. " + "doorbell: Doorbell camera events."), startTime: z .string() .datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true }) .describe("A timestamp representing when to start the search for access control events." + ISOTimestampFormatDescription), endTime: z .string() .datetime({ message: "Invalid datetime string. Expected ISO 8601 format.", offset: true }) .describe("A timestamp representing when to end the search for access control events." + ISOTimestampFormatDescription), accessControlledDoorUuids: z .array(z.string()) .nullable() .describe("The UUIDs (array) of the access controlled doors. Required when eventType is 'access-control'."), deviceUuid: z .string() .nullable() .describe("The UUID of the environmental gateway device. Required when eventType is 'environmental-gateway' Can be obtained from the get-entity-tool for ENVIRONMENTAL_GATEWAY."), sensorUuid: z .string() .nullable() .describe("The UUID of the climate sensor. Required when eventType is 'climate-sensor'. Can be obtained from the get-entity-tool for SENSOR."), limit: z .number() .int() .positive() .nullable() .describe("Maximum number of climate events to return. Only applicable when eventType is 'climate-sensor'. Default is 1000. Pass null for other event types."), locationUuid: z .string() .nullable() .describe("The UUID of the location. Required when eventType is 'component-events'."), componentEventTypes: z .array(z.nativeEnum(ComponentEventEnumType)) .nullable() .describe("Array of component event types to filter by. Only applicable when eventType is 'component-events'. " + "If empty or null, returns all event types. Valid values: " + "DoorbellEvent, DoorReaderStateChangeEvent, DoorRelayStateChangeEvent, DoorPositionIndicatorStateChangeEvent, " + "RequestToExitStateChangeEvent, CredentialReceivedEvent, ButtonEvent, GenericInputStateChangeEvent, " + "GenericRelayStateChangeEvent, AccessControlUnitTamperEvent, AccessControlUnitLocationLockdownStateEvent, " + "DoorLocationLockdownStateEvent, PanicButtonEvent, AccessControlUnitBatteryStateChangeEvent, " + "WaveToUnlockIntentExpiredEvent, DoorStateChangeEvent, DoorAuthFirstInStateEvent, DoorScheduleFirstInStateEvent, " + "AccessControlUnitDoorFirstInStateEvent, AperioDoorExtensionStateEvent, AperioGatewayStateEvent, " + "AperioGatewayConnectionStateChangeEvent, AperioDtcEvent, AperioTamperStateEvent."), timeZone: z .string() .describe("The timezone of the requested locations or devices. This is necessary for the tool to produce accurate formatted timestamps."), cameraUuid: z .string() .nullable() .describe("The unique identifier for the camera. Required when eventType is 'camera'. Can be obtained from the get-entity-tool for CAMERA."), duration: z .number() .int() .positive() .nullable() .describe("Duration in seconds to search footage seekpoints. Required when eventType is 'camera'. Default is 3600 (1 hour)."), buttonSensorUuid: z .string() .nullable() .describe("The UUID of the button sensor. Required when eventType is 'button-press'."), occupancySensorUuid: z .string() .nullable() .describe("The UUID of the occupancy sensor. Required when eventType is 'occupancy'."), proximityTagUuids: z .array(z.string()) .nullable() .describe("Array of proximity tag UUIDs. Required when eventType is 'proximity'."), doorbellCameraUuid: z .string() .nullable() .describe("The UUID of the doorbell camera. Required when eventType is 'doorbell'."), tempUnit: z .nativeEnum(TempUnit) .nullable() .describe("The unit of temperature to return. Default is Celsius."), }; const TOOL_ARGS_SCHEMA = z.object(TOOL_ARGS); const StrippedEnvironmentalEvent = z.object({ timestampString: z.string().optional().describe("Human-readable formatted timestamp"), temp: z.number().optional().describe("Temperature from CO2 sensor in Celsius"), probeTemp: z.number().optional().describe("Temperature from probe sensor in Celsius"), humidity: z.number().optional().describe("Relative humidity percentage"), pm25: z.number().optional().describe("PM2.5 particulate matter reading"), co2: z.number().optional().describe("CO2 concentration in PPM"), vapeDetected: z.boolean().optional().describe("Whether vape was detected"), }); const ClimateSensorEvent = z.object({ timestampString: z.string().optional().describe("Human-readable formatted timestamp"), timestampMs: z.number().optional().describe("Timestamp in milliseconds"), temp: z.number().optional().describe("Temperature reading in Celsius"), probeTemp: z.number().optional().describe("Temperature from probe sensor"), // probeTempC: z.number().optional().describe("Temperature from probe sensor in Celsius"), humidity: z.number().optional().describe("Relative humidity percentage"), pm25: z.number().optional().describe("PM2.5 particulate matter reading"), co2: z.number().optional().describe("CO2 concentration in PPM"), tvoc: z.number().optional().describe("Total Volatile Organic Compounds"), iaq: z.number().optional().describe("Indoor Air Quality index"), ethanol: z.number().optional().describe("Ethanol concentration"), heatIndexDegF: z.number().optional().describe("Heat index in Fahrenheit"), heatIndexRangeWarning: z.string().optional().describe("Heat index warning level"), vapeSmokeDetected: z.boolean().optional().describe("Whether vape or smoke was detected"), vapeSmokePercent: z.number().optional().describe("Vape/smoke confidence percentage"), thcDetected: z.boolean().optional().describe("Whether THC was detected"), thcPercent: z.number().optional().describe("THC confidence percentage"), tampered: z.boolean().optional().describe("Whether the sensor was tampered with"), batteryPercentage: z.number().optional().describe("Battery level percentage"), locationUuid: z.string().optional().describe("Location UUID"), orgUuid: z.string().optional().describe("Organization UUID"), }); export const OUTPUT_SCHEMA = z.object({ eventType: z .enum([ "access-control", "brivo-access-control", "environmental-gateway", "climate-sensor", "component-events", "camera", "button-press", "occupancy", "proximity", "doorbell", ]) .optional(), brivoAccessControlEvents: z.optional(z .object({ integrationEnabled: z.boolean().describe("Whether the Brivo integration is enabled"), brivoDoorsConfigured: z .number() .describe("Number of Brivo doors configured in the integration"), brivoDoors: z .array(z.object({ brivoDoornId: z.string().describe("Brivo's door ID"), doorName: z.string().optional().describe("Brivo door name"), locationUuid: z.string().optional().describe("Rhombus location UUID for this door"), })) .describe("List of Brivo doors configured in the integration"), events: z .array(z.object({ authenticationResult: z .string() .optional() .describe("The result of the authentication process"), authorizationResult: z .string() .optional() .describe("The result of the authorization process"), doorUuid: z .string() .optional() .describe("The Rhombus access controlled door UUID"), locationUuid: z .string() .optional() .describe("The Rhombus location UUID where the event occurred"), user: z.string().optional().describe("Username of the person who triggered the event"), credSource: z .string() .optional() .describe("The source of the credential (e.g. WIEGAND, NFC, BLE_WAVE, REMOTE)"), timestampMs: z .number() .optional() .describe("Timestamp in milliseconds when the event occurred"), datetime: z.string().optional().describe("Formatted datetime string of the event"), })) .describe("Credential received events from locations that have Brivo doors configured, sorted by timestamp (newest first)"), }) .nullable() .describe("Brivo access control events. Fetches credential events from all locations that have Brivo doors configured in the integration.")), accessControlEvents: z.optional(z .array(z.object({ authenticationResult: z .string() .optional() .describe("The result of the authentication process"), authorizationResult: z .string() .optional() .describe("The result of the authorization process"), doorUuid: z .string() .optional() .describe("The unique identifier for the access controlled door"), locationUuid: z .string() .optional() .describe("The unique identifier for the location where the event occurred"), user: z .string() .optional() .describe("The username of the person who triggered the event"), credSource: z .string() .optional() .describe("The source of the credential. Is what generated the event. " + "BLE_WAVE is a user badging in by physically waving their hand over the reader. " + "NFC is a user badging in by tapping their badge or their phone on the reader. " + "REMOTE is unlocking the door remotely through the Rhombus app."), timestampMs: z .number() .optional() .describe("Timestamp in milliseconds when the event occurred"), datetime: z.string().optional().describe("Datetime string of when the event occurred"), })) .nullable() .describe("Access control events data including badge ins, credentials, arrivals, etc., sorted by timestamp (newest first).")), environmentalGatewayEvents: z.optional(z .object({ events: z .array(StrippedEnvironmentalEvent) .optional() .describe("An array where each object represents a single environmental event containing sensor readings and derived values"), lastEvaluatedKey: z .string() .optional() .describe("A key for pagination if more results are available"), }) .nullable() .describe("Environmental gateway events data including sensor readings and derived values")), climateSensorEvents: z.optional(z .array(ClimateSensorEvent) .nullable() .describe("Climate sensor events data including temperature, humidity, air quality, and other readings")), componentEvents: z.optional(z .array(z.object({ eventType: z .string() .optional() .describe("The type of component event (e.g., DoorbellEvent, CredentialReceivedEvent, etc.)"), componentUuid: z .string() .optional() .describe("The unique identifier for the component that generated the event"), locationUuid: z .string() .optional() .describe("The unique identifier for the location where the event occurred"), orgUuid: z.string().optional().describe("The unique identifier for the organization"), correlationId: z .string() .optional() .describe("A correlation ID for tracking related events"), ownerDeviceUuid: z .string() .optional() .describe("The unique identifier for the device that owns this component"), datetime: z .string() .optional() .describe("Human-readable datetime string of when the event occurred"), timestampMs: z .number() .optional() .describe("Timestamp in milliseconds when the event occurred"), uuid: z.string().optional().describe("The unique identifier for this specific event"), // Event-specific fields authenticationResult: z .string() .optional() .describe("The result of the authentication process (for credential events)"), authorizationResult: z .string() .optional() .describe("The result of the authorization process (for credential events)"), user: z .string() .optional() .describe("The username of the person who triggered the event (for credential events)"), credSource: z .string() .optional() .describe("The source of the credential (for credential events)"), doorUuid: z .string() .optional() .describe("The unique identifier for the door (for door-related events)"), doorbellCameraUuid: z .string() .optional() .describe("The unique identifier for the doorbell camera (for doorbell events)"), previousState: z .string() .optional() .describe("The previous state before the change (for state change events)"), newState: z .string() .optional() .describe("The new state after the change (for state change events)"), reason: z.string().optional().describe("The reason for the state change or event"), buttonState: z .string() .optional() .describe("The state of the button (for button events)"), })) .nullable() .describe("Component events data for all types of access control events at a location, sorted by timestamp (newest first)")), cameraEvents: z .array(CameraFootageEvent) .optional() .describe(`Footage timeline seekpoints for the camera (all activity types returned in the window). Use with eventType "${EventsToolRequestType.CAMERA}".`), buttonPressEvents: z .array(z.object({ timestampMs: z.number().optional(), datetime: z.string().optional(), sensorUuid: z.string().optional(), buttonState: z.string().optional(), })) .optional() .describe("Button press events"), occupancyEvents: z .array(z.object({ timestampMs: z.number().optional(), datetime: z.string().optional(), sensorUuid: z.string().optional(), count: z.number().optional(), })) .optional() .describe("Occupancy sensor events"), proximityEvents: z .array(z.object({ timestampMs: z.number().optional(), datetime: z.string().optional(), tagUuid: z.string().optional(), rssi: z.number().optional(), })) .optional() .describe("Proximity tag events"), doorbellEvents: z .array(z.object({ timestampMs: z.number().optional(), datetime: z.string().optional(), doorbellCameraUuid: z.string().optional(), eventType: z.string().optional(), })) .optional() .describe("Doorbell camera events"), needUserInput: z.boolean().optional(), commandForUser: z.string().optional(), });