Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 44 Next »

This document outlines the GraphQL Occupancy API V2, which uses the Occupancy Aggregator service. Key updates include support for zone and floor queries, label aggregation, hybrid parking types, and two types of real-time subscriptions. The API is designed for efficient real-time parking space data retrieval and management, supporting various use cases from individual space monitoring to group and zone-level occupancy tracking.

Authorization

In order to authorize with this API, you need to add the following header to your request:

Key

Value

Authorization

<your token>

This API is available at the following url:

https://occupancy.api.nwave.io/graphql

Your token can be obtained from the Company Info section of the Nwave’s console.

You are not able to make API calls more frequently, than 300 times per 5 minutes with the same token. If amount of requests exceeds the limit, API reponds with error until the end of the 5 minute interval.

Objects/Types

In GraphQL, an object is a type that defines the structure of data returned by the API. Each field can represent a specific piece of data or a link to other objects. When a client queries the API, they can specify which fields of the object they want to include in the response, allowing for customized and efficient data retrieval.

Occupancy Summary

type OccupancySummary {
    total: Int
    occupied: Int
    available: Int
    undefined: Int
}

The OccupancySummary object provides an overview of parking availability at various levels of the system hierarchy, including Group, Level, Zone, and Project. It summarizes key metrics like the number of available, occupied, and total spaces to give a clear picture of the current usage and capacity at each level.

Location

type Location {
    lat: Float!
    lon: Float!
}

The Location object represents the geographical coordinates (latitude and longitude) of a specific point, used to define the position of parking space.

Project Occupancy

type ProjectOccupancy {
    id: ID!
    name: String
    location: Location
    occupancy: OccupancySummary!
}

The ProjectOccupancy object provides a summary of parking availability and usage across an entire project. It includes details about the project's location and name, giving an overall occupancy.

Zone Occupancy

type ZoneOccupancy {
    id: ID!
    name: String
    projectId: String!
    location: Location
    occupancy: OccupancySummary!
}

The ZoneOccupancy object gives a summary of parking availability within a specific zone. It includes the zone's location, name, and project association to provide a focused view of parking status within that area.

Level Occupancy

type LevelOccupancy {
    id: ID!
    name: String
    zoneId: Int!
    projectId: Int!
    floorNumber: Int
    occupancy: OccupancySummary!
}

The LevelOccupancy object provides a summary of parking availability on a specific floor or level of a parking facility. It includes identifiers for the level, zone, and project, along with the floor number and occupancy data to give an accurate view of parking status on that level.

Group Occupancy

type GroupOccupancy {
    id: ID!
    projectId: Int!
    zoneId: Int!
    levelId: Int!
    name: String
    groupType: String!
    customId: String
    locations: [Location!]!
    occupancy: OccupancySummary!
}

The GroupOccupancy object provides an overview of parking availability for a group of spaces located on a single level within a zone. It includes a group type and identifiers for the project, zone, and level, along with the specific locations of each position within the group.

Position Occupancy

type PositionOccupancy {
    id: ID!
    customId: String
    groupId: Int!
    zoneId: Int!
    levelId: Int!
    projectId: Int!
    occupancyStatus: OccupancyStatus!
    statusChangeTime: AWSDateTime
    location: Location!
    labels: [String!]
}

The PositionOccupancy object represents the real-time occupancy data of a specific parking space, indicating its current availability and when that status last changed. It includes detailed identifiers for its group, zone, level, and project, along with the space’s exact location.

Create Subscription Response

type CreateSubscriptionResponse {
  expiresOn: AWSDateTime!
  id: ID!
}

A return type for all subscription creation and update mutations. Contains:

  • id: A unique identifier used for subscribing to and listening for changes on this subscription

  • expiresOn: The timestamp when the subscription will expire if not renewed

Occupancy Snapshot

type OccupancySnapshot {
  groups: [GroupOccupancy!]
  id: ID!
  levels: [LevelOccupancy!]
  occupancy: OccupancySummary
  positions: [PositionOccupancy!]
  projects: [ProjectOccupancy!]
  zones: [ZoneOccupancy!]
}

Contains the complete occupancy state of the entities matching the subscription filters. Includes:

  • groups: Array of group occupancy data

  • id: Unique identifier for the snapshot

  • levels: Array of level occupancy data

  • occupancy: Overall occupancy summary

  • positions: Array of individual parking space data

  • projects: Array of project occupancy data

  • zones: Array of zone occupancy data

Subscription Occupancy Snapshot

type SubscriptionOccupancySnapshot {
  filters: [OccupancySnapshot!]!
  id: ID!
  time: AWSDateTime!
}

The return type when listening to a Snapshot subscription. Contains the complete state of all subscribed entities at the time of update.

Subscription Occupancy Updates

type SubscriptionOccupancyUpdates {
  group: GroupOccupancy
  id: ID!
  level: LevelOccupancy
  position: PositionOccupancy
  project: ProjectOccupancy
  time: AWSDateTime!
  zone: ZoneOccupancy
}

The return type when listening to an Updates subscription. Contains only the changed entities since the last update.

Enums

Check Consistency

enum CheckConsistency {
  hierarchy
}

Verifies that filters are consistent with the parking facility hierarchy:

  • hierarchy: Ensures entities exist within their parent containers (e.g., zones within specified projects, groups within specified zones)

Group By

enum GroupBy {
  group
  level
  position
  project
  zone
}

Determines the hierarchical level at which occupancy updates are aggregated:

  • group: Aggregates at the parking group level

  • level: Aggregates at the floor/level

  • position: Provides individual parking space updates

  • project: Aggregates at the project level

  • zone: Aggregates at the zone level

Labels Match

enum LabelsMatch {
  all
  any
  exclude
}

Defines the matching logic for filtering positions by multiple labels:

  • all: Matches positions that have all specified labels

  • any: Matches positions that have at least one of the specified labels

  • exclude: Matches positions that have none of the specified labels

Occupancy Status

enum OccupancyStatus {
  Free
  Occupied
  Undefined
}

Represents the current status of a parking position:

  • Free: Available parking space

  • Occupied: Space currently in use

  • Undefined: Status cannot be determined (e.g., device removed or experiencing errors)

Queries

In GraphQL, a Query is similar to a GET request in traditional APIs, where the client requests data from the server. Clients can pass query parameters to filter or specify the data they need, making queries customizable and efficient. Each query defines what fields to retrieve, and the server responds with only the requested data.

Project Queries

Example use case: A parking management company uses a centralized dashboard to monitor parking occupancy across multiple projects and locations. The dashboard provides a global view of parking availability and usage statistics, helping the company analyze trends, optimize capacity, and make informed decisions on pricing or resource allocation. The query retrieves occupancy data for multiple projects, showing total, available, and occupied spaces.

findProjectOccupancies(
  id: [Int!],
  lat: Float,
  lon: Float,
  distanceMeters: Int,
  networkId: [String!],
  groupId: [Int!],
  levelId: [Int!],
  labels: [String!],
  labelsMatch: LabelsMatch,
  floorNumber: [Int!],
  zoneId: [Int!],
  groupCustomId: [String!],
  limit: Int = 100,
  offset: Int = 0
): [ProjectOccupancy]
{
  findProjectOccupancies(
    projectId: [101, 202, 303]
  ) {
    id
    name
    location {
      lat
      lon
    }
    occupancy {
      total
      available
      occupied
    }
  }
}

Zone Queries

Example use case: A mobile app helps drivers find available parking zones near their current location. The app allows users to specify the maximum distance from their location and shows the available parking spaces in nearby zones.

findZoneOccupancies(
  id: [Int!],
  lat: Float,
  lon: Float,
  distanceMeters: Int,
  networkId: [String!],
  groupId: [Int!],
  levelId: [Int!],
  labels: [String!],
  labelsMatch: LabelsMatch,
  floorNumber: [Int!],
  projectId: [Int!],
  groupCustomId: [String!],
  limit: Int = 100,
  offset: Int = 0
): [ZoneOccupancy]
{
  findZoneOccupancies(
    lat: 37.7749,
    lon: -122.4194,
    distanceMeters: 5000,
  ) {
    name
    location {
      lat
      lon
    }
    occupancy {
      available
    }
  }
}

Level Queries

Example use case: A parking facility is equipped with digital signage to help drivers locate available parking spaces on different levels. The digital signage system periodically queries the parking management system to retrieve the latest occupancy data for each level and displays the number of available spots on each floor. The system filters by specific zone and project IDs to ensure it only retrieves data for relevant sections of the parking facility.

findLevelOccupancies(
  id: [Int!],
  lat: Float,
  lon: Float,
  distanceMeters: Int,
  networkId: [String!],
  groupId: [Int!],
  labels: [String!],
  labelsMatch: LabelsMatch,
  floorNumber: [Int!],
  zoneId: [Int!],
  projectId: [Int!],
  groupCustomId: [String!],
  limit: Int = 100,
  offset: Int = 0
): [LevelOccupancy]
{
  findLevelOccupancies(
    zoneId: [5],
    projectId: [101],
    floorNumber: [1, 2, 3],
  ) {
    id
    name
    floorNumber
    occupancy {
      total
      available
      occupied
    }
  }
}

Group Queries

Example use case: A city has implemented digital signage to guide drivers to available EV parking spots in outdoor street parking zones. The system uses parking occupancy data filtered for groups of EV-designated spots and displays the availability on signage near high-traffic areas. This reduces emissions by minimizing the time drivers spend searching for EV parking, thus supporting the city’s environmental goals.

findGroupOccupancies(
  id: [Int!],
  lat: Float,
  lon: Float,
  distanceMeters: Int,
  networkId: [String!],
  levelId: [Int!],
  labels: [String!],
  labelsMatch: LabelsMatch,
  floorNumber: [Int!],
  zoneId: [Int!],
  projectId: [Int!],
  groupCustomId: [String!],
  limit: Int = 100,
  offset: Int = 0
): [GroupOccupancy]
{
  findGroupOccupancies(
    labels: ["EV"],
    labelsMatch: any,
    zoneId: [10, 22],
  ) {
    id
    name
    groupType
    locations {
      lat
      lon
    }
    occupancy {
      total
      available
      occupied
    }
  }
}

Position Queries

Example use case: A mobile app is designed to help drivers locate and navigate to individual parking spots within a parking facility. The app displays a map that shows the exact location of available parking spaces and guides the driver to the nearest free spot. The query retrieves data for individual parking positions, including their occupancy status and location, allowing the app to highlight available spaces on the map.

findPositionOccupancies(
  id: [String!],
  lat: Float,
  lon: Float,
  distanceMeters: Int,
  groupId: [Int!],
  levelId: [Int!],
  labels: [String!],
  labelsMatch: LabelsMatch,
  floorNumber: [Int!],
  zoneId: [Int!],
  projectId: [Int!],
  groupCustomId: [String!],
  limit: Int = 100,
  offset: Int = 0
): [PositionOccupancy]
{
  findPositionOccupancies(
    lat: 40.7128,
    lon: -74.0060,
    distanceMeters: 500,
    labels: ["EV"],
    labelsMatch: any,
    zoneId: [7]
  ) {
    id
    location {
      lat
      lon
    }
    occupancyStatus
    statusChangeTime
  }

Mutations and Subscriptions

Subscrption Types

This API enables the creation of subscriptions and provides real-time updates about these subscriptions. There are two types of subscriptions available:

  1. Snapshot Subscriptions: Provide complete occupancy data for the subscribed entities whenever any change occurs.

  2. Update Subscriptions: Provide only the changed occupancy data, making them more efficient for real-time updates.

In GraphQL, a mutation is used to modify or create data on the server, similar to POST, PUT, or DELETE requests in REST APIs. In our use case, mutations are used to create and update subscriptions, allowing clients to manage parking-related subscriptions.

Subscription expiry

The subscription expiry time is automatically extended after each update. To extend a subscription without changing its parameters you should use the keepAliveSubscription mutation.

Create Snapshot Subscription

Example use case: This mutation creates a subscription to monitor parking availability in zones 10 and 11 within project 101. It uses a zone-based grouping (groupBy: zone) and filters for parking spaces labeled as EV. The subscription is limited to a 5,000-meter radius around the given coordinates (latitude: 37.7749, longitude: -122.4194). The labelsMatch: any ensures that any space marked as EV will be included. The mutation response will include a unique subscription id and an expiresOn field, indicating when the subscription will expire.

createSubscriptionOccupancySnapshot(
  filters: [FilterInput!]!,
  checkConsistency: [CheckConsistency!]
): CreateSubscriptionResponse!
mutation {
  createSubscriptionOccupancySnapshot(
    filters: [{
      projectId: [101],
      zoneId: [10, 11],
      area: {
        latitude: 37.7749,
        longitude: -122.4194,
        distanceMeters: 5000
      },
      labels: ["EV"],
      labelsMatch: any,
      groupBy: zone
    }]
  ) {
    id
    expiresOn
  }
}

Create Updates Subscription

Example use case: When monitoring a large parking facility, receiving only changed data can significantly reduce bandwidth usage. This subscription will only return information about spaces that have changed their occupancy status.

createSubscriptionOccupancyUpdates(
  projectId: [Int!],
  zoneId: [Int!],
  levelId: [Int!],
  floorNumber: [Int!],
  groupId: [Int!],
  groupCustomId: [String!],
  networkId: [String!],
  labels: [String!],
  labelsMatch: LabelsMatch,
  area: LocationWithRadiusInput,
  groupBy: GroupBy!,
  checkConsistency: [CheckConsistency!]
): CreateSubscriptionResponse!
mutation {
  createSubscriptionOccupancyUpdates(
    projectId: [101],
    zoneId: [10, 11],
    area: {
      latitude: 37.7749,
      longitude: -122.4194,
      distanceMeters: 5000
    },
    labels: ["EV"],
    labelsMatch: any,
    groupBy: zone
  ) {
    id
    expiresOn
  }
}

Subscription Updates Warning

Important: Sending an empty update will result in clearing all subscription parameters, which may disrupt the functionality of the subscription. Always ensure to include the full set of original parameters when extending or modifying a subscription to avoid unintended data loss or disruptions.

Update Snapshot Subscription

Example use case: In this mobile app scenario, the user initially subscribed to parking availability within a 5,000-meter radius, but as they zoom in on the map, the subscription needs to be adjusted to a smaller area.

mutation {
  updateSubscriptionOccupancySnapshot(
    id: "12345",
    filters: [{
      projectId: [101],
      zoneId: [10, 11],
      area: {
        latitude: 37.7749,
        longitude: -122.4194,
        distanceMeters: 1000  # Updated
      },
      labels: ["EV"],
      labelsMatch: any,
      groupBy: position  # Updated
    }]
  ) {
    id
    expiresOn
  }
}

Update Updates Subscription

Similar to updating snapshot subscriptions, but for the more efficient updates-only subscription

mutation {
  updateSubscriptionOccupancyUpdates(
    id: "12345",
    projectId: [101],
    zoneId: [10, 11],
    area: {
      latitude: 37.7749,
      longitude: -122.4194,
      distanceMeters: 1000
    },
    labels: ["EV"],
    labelsMatch: any,
    groupBy: position
  ) {
    id
    expiresOn
  }
}

Demand Snapshot

Example use case: During testing or debugging, you may need to manually trigger a complete data update.

mutation {
  demandSubscriptionOccupancySnapshot(id: "12345")
}

Keep Alive Subscirption

Extends the expiration time of any subscription without modifying its parameters.

mutation {
  keepAliveSubscription(id: "12345") {
    id
    expiresOn
  }
}

GraphQL Schema

  • No labels