Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Note

GraphQL API v1 is going to be deprecated in 2024Q3. If you plan to use GraphQL API, please, refer to the GraphQL Occupancy API V2

Table of Contents

GraphQL Occupancy API offers similar functionality to REST Occupancy API, however, there are additional benefits to using GraphQL.

You can select the fields you want to receive from the API. By requesting only the required fields from the API you can decrease traffic and consequently increase load speed.

Additionally, GraphQL Occupancy API supports subscriptions, which allows you to receive real-time occupancy updates.

Authorization

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

Key

Value

Authorization

<your token>

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

Object & Field Descriptions

PositionOccupancy - describes a position and its occupancy state

  • id - position id

  • customId - user-defined id

  • groupId - position’s group id

  • occupancyStatus - parking space occupancy status

  • statusChangeTime - latest occupancy status change time

  • location - object containing latitude and longitude coordinates
  • GroupOccupancy - describes a group, its positions and their occupancy states

    • id - group id

    • name - group user-defined name

    • customId - group user-defined id

    • location - object containing latitude and longitude coordinates

    • positionsOccupancy - list of all positions inside a group with its occupancy information

    • summary - group occupancy summary (total positions number, number of occupied and free positions)

  • Info

    The summary object should be used to display availability for all parking group types

    • SubscriptionArea - special object for describing occupancy states changes for some area

      • id - area id

      • location - object containing latitude and longitude coordinates

      • radius - area’s radius in meters

      • granularity - user-defined type for returned objects. Available values: [Position, Level, Group, Zone]

      • updates - list of Occupancy objects. Type of objects depends on the selected granularity option.

      • updateTime - the time of last occupancy status update

    Documentation

    The following GraphQL schema describes data types and operations that can be performed.

    schema { query: Query mutation: Mutation subscription: Subscription } enum OccupancyStatus { Occupied Free } enum SubscriptionGranularity { Position Level Group Zone
    Code Block
    languagegraphql
    Note

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

    GraphQL Schema

    The following GraphQL schema describes data types and operations that can be performed.

    Expand
    titleschema.graphql
    Code Block
    languagegraphql
    type GroupOccupancy @aws_api_key
    @aws_lambda {
    	id: ID!
    	zoneId: Int
    	levelId: Int
    	name: String!
    	groupType: String!
    	customId: String
    	location: Location
    	positionsOccupancy: [PositionOccupancy]
    	summary: OccupancySummary
    }
    
    input GroupOccupancyInput {
    	id: ID!
    	zoneId: Int
    	levelId: Int
    	name: String!
    	groupType: String!
    	customId: String
    	location: LocationInput!
    	positionsOccupancy: [PositionOccupancyInput!]!
    	summary: OccupancySummaryInput!
    }
    
    type LevelOccupancy @aws_api_key
    @aws_lambda {
    	id: Int
    	name: String
    	zoneId: Int!
    	floorNumber: Int
    	summary: OccupancySummary
    }
    
    input LevelOccupancyInput {
    	id: Int
    	zoneId: Int!
    	floorNumber: Int
    	name: String
    	summary: OccupancySummaryInput!
    }
    
    type Location @aws_api_key
    @aws_lambda {
    
    	lat: Float!
    
    	lon: Float!
    }
    
    input LocationInput {
    	lat: 
    lat
    Float!
    	lon: Float!
    }
    
    enum 
    lon: Float!
    OccupancyStatus {
    	Occupied
    	Free
    }
    
    type OccupancySummary 
    @aws_api_key
    @aws_lambda {
    
    	total: Int!
    
    	occupied: Int!
    
    	available: Int!
    
    	undefined: Int!
    }
    
    input OccupancySummaryInput {
    
    	total: Int!
    
    	occupied: Int!
    
    	available: Int!
    
    undefined:
    	undefined: Int!
    }
    
    type PositionOccupancy 
    @aws_api_key
    @aws_lambda {
    
    	id: 
    Int
    ID!
    
    	customId: String
    
    	groupId: Int
    
    	occupancyStatus: OccupancyStatus
    
    	statusChangeTime: AWSDateTime
    
    	location: Location!
    	labels: [String]
    }
    
    input PositionOccupancyInput {
    
    	id: 
    Int
    ID!
    
    	customId: String
    
    	groupId: Int!
    
    	occupancyStatus: OccupancyStatus!
    
    	statusChangeTime: AWSDateTime!
    
    	location: LocationInput!
    	labels: [String]
    }
    
    
    type
    union RtaUpdateObject = ZoneOccupancy | LevelOccupancy | GroupOccupancy 
    @aws_api_key @aws_lambda {
    | PositionOccupancy 
    
    interface SubscriptionArea {
    	id: 
    Int
    ID!
    	location: Location
    	radius: Int
    	zoneId: [Int]
    
    	levelId: [Int]
    	floorNumber: [Int]
    	groupId: [Int]
    
    name
    	labels: [String
    !
    ]
    	granularity: 
    groupType
    SubscriptionGranularity!
    	expiresOn: 
    String
    AWSDateTime!
    }
    
    type SubscriptionAreaNoUpdates 
    customId:
    implements 
    String
    SubscriptionArea @aws_api_key
    @aws_lambda {
    	id: ID!
    	location: Location
    	radius: Int
    	zoneId: [Int]
    	levelId: [Int]
    	floorNumber: [Int]
    
    positionsOccupancy
    	groupId: [
    PositionOccupancy
    Int]
    	labels: [String]
    	granularity: SubscriptionGranularity!
    
    summary
    	expiresOn: 
    OccupancySummary
    AWSDateTime!
    }
    
    
    input
    type 
    GroupOccupancyInput
    SubscriptionAreaWithUpdates 
    {
    implements SubscriptionArea @aws_api_key
    @aws_lambda {
    	id: 
    Int
    ID!
    	location: Location
    
    	radius: Int
    	zoneId: [Int]
    	levelId: [Int]
    	floorNumber: [Int]
    
    levelId
    	groupId: [Int]
    	labels: [String]
    	granularity: SubscriptionGranularity!
    
    name
    	expiresOn: 
    String
    AWSDateTime!
    	updates: 
    groupType
    [RtaUpdateObject]
    	updateTime: 
    String!
    AWSDateTime
    }
    
    enum SubscriptionGranularity 
    customId:
    {
    
    String
    	Position
    	Level
    	Group
    	Zone
    }
    
    location:
    
    
    LocationInput!
    type ZoneOccupancy @aws_api_key
    @aws_lambda {
    
    positionsOccupancy
    	id: 
    [PositionOccupancyInput!]
    ID!
    	name: String!
    	projectId: Int
    	summary: 
    OccupancySummaryInput!
    OccupancySummary
    }
    
    
    type LevelOccupancy @aws_api_key @aws_lambda
    input ZoneOccupancyInput {
    
    	id: 
    Int
    ID!
    	name: String
    zoneId: Int
    !
    
    floorNumber
    	projectId: Int
    
    	summary: 
    OccupancySummary
    OccupancySummaryInput!
    }
    
    
    input
    type 
    LevelOccupancyInput
    Mutation {
    	createSubscriptionArea(
    		lat: 
    id
    Float,
    		lon: 
    Int
    Float,
    		radius: Int,
    		zoneId: [Int
    !
    ],
    		levelId: [Int],
    		floorNumber: [Int],
    		groupId: 
    name
    [Int],
    		labels: [String],
    		granularity: SubscriptionGranularity
    
    summary
    	): 
    OccupancySummaryInput! } type ZoneOccupancy
    SubscriptionAreaNoUpdates
    		@aws_api_key
    @aws_lambda
    
    {
    	updateSubscriptionArea(
    		id: 
    Int
    ID!,
    
    name: String! projectId: String summary: OccupancySummary } input ZoneOccupancyInput { id: Int! name: String! projectId: Int summary: OccupancySummaryInput! } union RtaUpdateObject = ZoneOccupancy | LevelOccupancy | GroupOccupancy | PositionOccupancy interface SubscriptionArea { id: Int! location: Location radius: Int zoneId: [Int] levelId: [Int] floorNumber: [Int] groupId: [Int] labels: [String] granularity: SubscriptionGranularity! expiresOn: AWSDateTime! } type SubscriptionAreaNoUpdates implements SubscriptionArea @aws_api_key @aws_lambda { id: Int! location: Location radius: Int zoneId: [Int] levelId: [Int] floorNumber: [Int] groupId: [Int] labels: [String] granularity: SubscriptionGranularity! expiresOn: AWSDateTime! } type SubscriptionAreaWithUpdates implements SubscriptionArea @aws_api_key @aws_lambda { id: Int! location: Location radius: Int zoneId: [Int] levelId: [Int] floorNumber: [Int] groupId: [Int] labels: [String] granularity: SubscriptionGranularity! expiresOn: AWSDateTime! updates: [RtaUpdateObject] updateTime: AWSDateTime
    		lat: Float,
    		lon: Float,
    		radius: Int,
    		zoneId: [Int],
    		levelId: [Int],
    		floorNumber: [Int],
    		groupId: [Int],
    		labels: [String],
    		granularity: SubscriptionGranularity
    	): SubscriptionAreaNoUpdates
    		@aws_api_key
    @aws_lambda
    	updatePositionOccupancy(positionId: Int!, occupancyStatus: OccupancyStatus!, timestamp: String!): PositionOccupancy
    		@aws_api_key
    	pushPositionUpdates(
    		id: ID!,
    		location: LocationInput,
    		radius: Int,
    		zoneId: [Int],
    		levelId: [Int],
    		floorNumber: [Int],
    		groupId: [Int],
    		labels: [String],
    		granularity: SubscriptionGranularity!,
    		expiresOn: AWSDateTime!,
    		updates: [PositionOccupancyInput!]!,
    		updateTime: String!
    	): SubscriptionAreaWithUpdates
    		@aws_api_key
    	pushGroupUpdates(
    		id: ID!,
    		location: LocationInput,
    		radius: Int,
    		zoneId: [Int],
    		levelId: [Int],
    		floorNumber: [Int],
    		groupId: [Int],
    		labels: [String],
    		granularity: SubscriptionGranularity!,
    		expiresOn: AWSDateTime!,
    		updates: [GroupOccupancyInput!]!,
    		updateTime: String!
    	): SubscriptionAreaWithUpdates
    		@aws_api_key
    	pushLevelUpdates(
    		id: ID!,
    		location: LocationInput,
    		radius: Int,
    		zoneId: [Int],
    		levelId: [Int],
    		floorNumber: [Int],
    		groupId: [Int],
    		labels: [String],
    		granularity: SubscriptionGranularity!,
    		expiresOn: AWSDateTime!,
    		updates: [LevelOccupancyInput!]!,
    		updateTime: String!
    	): SubscriptionAreaWithUpdates
    		@aws_api_key
    	pushZoneUpdates(
    		id: ID!,
    		location: LocationInput,
    		radius: Int,
    		zoneId: [Int],
    		levelId: [Int],
    		floorNumber: [Int],
    		groupId: [Int],
    		labels: [String],
    		granularity: SubscriptionGranularity!,
    		expiresOn: AWSDateTime!,
    		updates: [ZoneOccupancyInput!]!,
    		updateTime: String!
    	): SubscriptionAreaWithUpdates
    		@aws_api_key
    }
    
    type Query {
    
    	groupOccupancy(id: 
    Int
    ID!): GroupOccupancy
    		@aws_api_key
    @aws_lambda
    
    	findGroupOccupancies(
    
    		ids: [Int]
    ,
    		lat: Float
    ,
    		lon: Float,
    		radius: 
    radius
    Int,
    		levelId: [Int
    levelId
    !],
    		labels: [
    Int
    String!]
    ,
    		floorNumber: [Int!]
    ,
    		zoneId: [Int!]
    ,
    		projectId: Int
    ,
    		groupCustomId: String
    ,
    		limit: Int,
    
    = 50 offset: Int )
    		offset: Int
    	): [GroupOccupancy]
    		@aws_api_key
    @aws_lambda
    
    	findPositionOccupancies(
    
    		ids: [Int]
    ,
    		lat: Float
    ,
    		lon: Float
    ,
    		radius: Int
    ,
    		groupId: [Int!],
    
    levelId
    		levelId: [Int!],
    		labels: [
    Int
    String!]
    ,
    		floorNumber: [Int!]
    ,
    		zoneId: [Int!]
    ,
    		projectId: Int
    ,
    		groupCustomId: String
    ,
    		limit: Int
    = 50
    ,
    		offset: Int
    
    ) : [
    	): [PositionOccupancy]
    		@aws_api_key
    @aws_lambda
    }
    
    type 
    Mutation
    Subscription {
    	onSubscriptionAreaUpdates(id: ID!): SubscriptionAreaWithUpdates
    		@aws_api_key
    
    createSubscriptionArea( lat: Float, lon: Float, radius: Int, zoneId: [Int], levelId: [Int], floorNumber: [Int], groupId: [Int], labels: [String], granularity: SubscriptionGranularity ): SubscriptionAreaNoUpdates @aws_api_key @aws_lambda updateSubscriptionArea( id: Int!, lat: Float, lon: Float, radius: Int, zoneId: [Int], levelId: [Int], floorNumber: [Int], groupId: [Int], labels: [String], granularity: SubscriptionGranularity ): SubscriptionAreaNoUpdates @aws_api_key @aws_lambda updatePositionOccupancy( positionId: Int!, occupancyStatus: OccupancyStatus!, timestamp: String! ): PositionOccupancy @aws_api_key pushPositionUpdates( id: Int!, location: LocationInput, radius: Int, zoneId: [Int], levelId: [Int], floorNumber: [Int], groupId: [Int], labels: [String], granularity: SubscriptionGranularity!, expiresOn: AWSDateTime!, updates: [PositionOccupancyInput!]!, updateTime: String! ): SubscriptionAreaWithUpdates @aws_api_key pushGroupUpdates( id: Int!, location: LocationInput, radius: Int, zoneId: [Int], levelId: [Int], floorNumber: [Int], groupId: [Int], labels: [String], granularity: SubscriptionGranularity!, expiresOn: AWSDateTime!, updates: [GroupOccupancyInput!]!, updateTime: String! ): SubscriptionAreaWithUpdates @aws_api_key pushLevelUpdates( id: Int!, location: LocationInput
    @aws_lambda
    @aws_subscribe(mutations: ["pushPositionUpdates","pushGroupUpdates","pushLevelUpdates","pushZoneUpdates"])
    }
    
    # @api_key (admin) auth and @aws_lambda (user) auth are required for all types apart from:
    ##   updatePositionOccupancy
    ##   pushPositionUpdates
    ##   pushGroupUpdates
    ##   pushLevelUpdates
    ##   pushZoneUpdates
    ## These are for internal subscription notification and should have exclusive admin access
    schema {
    	query: Query
    	mutation: Mutation
    	subscription: Subscription
    }

    Subscription Areas

    A subscription area is an object that has two main functions:

    1. Filtering of the incoming position updates

    2. Defining the format of updates that is received by subscribers

    There are two types defined in the GraphQL schema for Subscription Areas:

    SubscriptionAreaNoUpdates - this type is returned when you create or update a Subscription Area. It does not have ‘updates’ & ‘updateTime’ fields as updates are only returned to active subscriptions.

    Info

    Subscription areas expiry 5 minutes after creation. Any update of a subscription area, including an empty one, will extend the expiration time by 5 minutes from the time of update.

    SubscriptionAreaWithUpdates - this type is returned to subscribers and as the name suggests it contains the ‘updates’ & ‘updateTime’ fields.

    Subscription Area Filters

    Subscription Areas filter the incoming updates and only notify the subscribers if the incoming position update matches all of the filters. Subscription Area filters can also be split into 2 categories:

    1. Hierarchical Filters: zoneId, groupId, levelId, floorNumber, labels

    2. Geospatial Filters: lat, lon, radius

    Info

    A valid subscription area must have at least one hierarchical filter and/or all of the geospatial filters.

    A match is when all position attributes are a subset (⊆) of the Subscription Area filters and it implies that a given position is inside a Subscription Area.

    Subscription Area filter with null value matches everything.

    The following example is a valid match between Subscription Area and Position Update.

    Position

    1. zoneId: 1

    2. groupId: 2

    3. levelId: 3

    4. floorNumber: 4

    5. labels: ['EV', ‘Disabled’]

    6. lat: 0.0

    7. lon: 0.0

    Subscription Area

    1. zoneId: [1, 2, 3]

    2. groupId: [1, 2, 3]

    3. levelId: [3]

    4. floorNumber: null

    5. lables: ['EV', ‘Disabled’, ‘VIP’]

    6. lat: 0.0

    7. lon: 0.0

    8. radius: 100

    Note

    Geospatial filters create a circular search area on the map, and there can be cases when a group of devices partially falls into the search area. (e.g. Half a group is within the search area and half is outside of the search area).

    Updates for positions that do not fall into the search area would still notify the subscribers.

    Subscription Area Updates

    The updates field of a Subscription Area can contain a list of 4 different types. All types within the updates list are the same. The type you will receive in the updates field depends on the granularity you choose.

    Granularity

    Updates Type

    Zone

    ZoneOccupancy

    Level

    LevelOccupancy

    Group

    GroupOccupancy

    Position

    PositionOccupancy

    Info

    Updates field will always contain only the object that has changed and therfore the list should always have a length of 1.

    Object & Field Descriptions

    SubscirptionArea

    • id - subscription area id

    • location - center coordinates of the search area

    • radius - radius from the center in meeters that creates the search area

    • zoneId - list of zone ids to match

    • levelId - list of level ids to match

    • floorNumber - list of floor numbers to match

    • groupId - list of group ids to match

    • labels - list of labels to match

    • granularity - defines the updates type

    • expiresOn - timestamp of subscription area expiration

    • udpates - occupancy updates for a subscription area

    • updateTime - timestamp of the occupancy update

    ZoneOccupancy

    • id - zone id

    • name - zone name

    • projectId - project id

    • summary - summary of occupancies in the Zone

    LevelOccupancy

    • id - level id

    • name - level name

    • zoneId - zone id

    • floorNumber - floor number of a level

    • summary - summary of occupancies on a Level

    GroupOccupancy

    • id - group id

    • zoneId - zone id

    • levelId - level id

    • name - group name

    • groupType - group type e.g. marked_bay

    • customId - user defined group id

    • location - сenter coordinates of a group

    • positionOccupancy - list of PositionOccupancy objects for a group

    • summary - summary of occupancies in the Group

    PositionOccupancy

    • id - position id

    • customId - custom id

    • groupId - group id

    • occupancyStatus - ‘occupied’, ‘free’ or null

    • statusChangeTime - timestamp of last occupancyStatus change

    • location: coordinates of a position

    Info

    The summary object should be used to display availability for all parking group types as it handles unmarked bay occupancies

    Operations

    The following operations can be performed using either Postman or curl command except for subscription operations.

    groupOccupancy

    This query will return the occupancy of a single group.

    Query

    Code Block
    languagegraphql
    query MyQuery {
      groupOccupancy(id: 123) {
        id
        customId
        name
        location {
          lat
          lon
        }
        positionsOccupancy {
          customId
          id
          groupId
          labels
          location {
            lat
            lon
          }
          occupancyStatus
          statusChangeTime
        }
      }
    }

    Response

    Code Block
    languagejson
    {
      "data": {
        "groupOccupancy": {
          "id": 3544,
          "customId": null,
          "name": "Foo",
          "location": {
            "lat": 51.493601937687224,
            
    radius
    "lon": 
    Int,
    -0.12852029611716095
          
    zoneId: [Int]
    },
          
    levelId
    "positionsOccupancy": [
    Int],
    
            {
    
    floorNumber:
     
    [Int],
             
    groupId
    "customId": 
    [Int],
    "",
              
    labels
    "id": 
    [String]
    1,
              
    granularity
    "groupId": 
    SubscriptionGranularity!
    123,
            
    expiresOn
      "labels": 
    AWSDateTime!
    null,
            
    updates:
     
    [LevelOccupancyInput!]!,
     "location": {
          
    updateTime:
     
    String!
         
    )
    "lat": 
    SubscriptionAreaWithUpdates @aws_api_key
    51.49360068522545,
          
    pushZoneUpdates(
          "lon": -0.1286061268139623
     
    id:
     
    Int!,
            },
    
    location:
     
    LocationInput,
             
    radius
    "occupancyStatus": 
    Int
    "Free",
             
    zoneId: [Int],
     "statusChangeTime": "2021-01-27T19:22:47.548+00:00"
            
    levelId: [Int],
    },
            {
    
    floorNumber:
     
    [Int],
             
    groupId
    "customId": 
    [Int]
    "",
            
    labels
      "id": 
    [String]
    2,
            
    granularity
      "groupId": 
    SubscriptionGranularity!
    123,
            
    expiresOn
      "labels": 
    AWSDateTime!
    null,
            
    updates:
     
    [ZoneOccupancyInput!]!,
     "location": {
          
    updateTime:
     
    String!
         
    ): SubscriptionAreaWithUpdates @aws_api_key } type Subscription {
    "lat": 51.493601937687224,
               
    onSubscriptionAreaUpdates(id: Int!): SubscriptionAreaWithUpdates @aws_api_key @aws_lambda @aws_subscribe(mutations : ["pushPositionUpdates", "pushGroupUpdates", "pushLevelUpdates", "pushZoneUpdates"]) }

    Operations

    The following operations can be performed using either Postman or curl command except for subscription operations.

    groupOccupancy

    This query will return the occupancy of a single group.

    Query

    Code Block
    languagegraphql
    query MyQuery {
      groupOccupancy(id: 123) { "lon": -0.12852029611716098
              },
              "occupancyStatus": "Occupoed",
         id     customId
    "statusChangeTime": "2021-01-27T18:56:53.502+00:00"
       name     location}
    {      ]
    lat    }
      lon
        }
        positionsOccupancy}
    }

    findGroupOccupancies

    This query will return a list of group occupancies.

    Query

    Code Block
    languagegraphql
    query MyQuery {
      findGroupOccupancies(ids: [1234]) {
        id
     customId   location {
      id    lat
      groupId    lon
      location { }
        summary {
     lat     available
       lon   occupied
       }    total
      occupancyStatus    undefined
      statusChangeTime     }
      }
    }

     

    Response

    Code Block
    languagejson
    {
      "data": {
        "groupOccupancyfindGroupOccupancies": [
    {      {
    "id": 3544,       "customIdid": null,
          "name": "Foo",1234,
            "location": {
              "lat": 5150.493601937687224780416909504915,
              "lon": -0.12852029611716095 -1.0914407438684124
            },
            "positionsOccupancysummary": {
      [         {"available": 34,
              "customIdoccupied": ""13,
              "idtotal": 147,
              "groupIdundefined": 0
     123,       }
        "location": { }
        ]
      }
    }

    findPositionOccupancies

    This query will return a list of position occupancies.

    Query

    Code Block
    languagegraphql
    query MyQuery {
    "lat": 51.49360068522545,
       findPositionOccupancies(ids: [1]) {
        id
        "lon": -0.1286061268139623labels
        location {
         }, lat
          lon
      "occupancyStatus": "Free", }
        occupancyStatus
        "statusChangeTime": "2021-01-27T19:22:47.548+00:00"
        groupId
       }, customId
      }
    }

     

    Response

    Code Block
    languagejson
    {
      "data": {
        "findPositionOccupancies": [
        "customId": "",  {
            "id": 212345,
     
            "groupIdlabels": 123,
     ["EV", "VIP"],
            "location": {
    
               "lat": 51.49360193768722449360068522545,
                "lon": -0.12852029611716098
    1286061268139623
             },
     
            "occupancyStatus": "OccupoedFree",
              "statusChangeTime": "2021-01-27T1827T19:5622:5347.502548+00:00"
            }
          ]
        }
      }
    }

    findGroupOccupancies

    This query will return a list of group occupancies.

    Query

    Code Block
    languagegraphql
    query MyQuery {
      findGroupOccupancies(ids: [1234]) {
        id
        location {
          lat
          lon
        }
        summary {,
            "groupId": 123,
            "customId": ""
          }
        ]
      }
    }

    createSubscriptionArea

    This mutation will create a new subscription area.

    Subscription Area Expiration

    By default, subscription areas expire 5 minutes after creation. Once a subscription area is expired, it cannot be extended and subscribers will stop receiving updates.

    Mutation

    Code Block
    languagegraphql
    mutation MyMutation {
      createSubscriptionArea(
        granularity: Group, 
        lat: 51.493930, 
         availablelon: -0.129030, 
        radius: occupied100,
        labels: ["EV"]
    total  ) {
       undefined expiresOn
       }
      }
    }

     

    Response

    Code Block
    languagejson
    { granularity
      "data": {  id
      "findGroupOccupancies": [      location {
          lat
      "id": 1234,   lon
        }
    "location": {   radius
      }
    }
    

     

    Response

    Code Block
    languagejson
    {
      "latdata": {
    50.780416909504915,    "createSubscriptionArea": {
          "lonexpiresOn": -1.0914407438684124
            }"2021-01-28T23:20:06.232+00:00",
            "summarygranularity": {"Group",
              "availableid": 341,
     
            "occupiedlocation": 13,
    {
             "totallat": 4751.49393,
              "undefinedlon": -0.12903
          },
     }     "radius": 100
    }    }
    ]   }
    }

    findPositionOccupancies

    This query will return a list of position occupancies.

    Query
    }
    }

    onSubscriptionAreaUpdates

    This subscription will subscribe to occupancy updates inside an area.

    Selected updates object type must correspond to the granularity of the created search area:

    1. granularity: Position → updates { … on PositionOccupancy }

    2. granularity: Group → updates { … on GroupOccupancy }

    If you are unsure of the granularity for your subscription area, you can specify both types inside the updates.

    Subscription

    Code Block
    languagegraphql
    querysubscription MyQueryMySubscription {
      findPositionOccupanciesonSubscriptionAreaUpdates(idsid: [1]) {
        id
        locationexpiresOn
    {    granularity
      lat  location {
       lon    lat
    }     occupancyStatus lon
       statusChangeTime }
       groupId
        customId
      }
    }

     

    Response

    Code Block
    languagejson
    { radius
       "data": {updateTime
        "findPositionOccupancies": [updates {
          {... on GroupOccupancy {
         "id": 12345,  id
          "location": { name
            customId
    "lat": 51.49360068522545,       location {
      "lon": -0.1286061268139623       lat
     },         "occupancyStatus": "Free",lon
            }
    "statusChangeTime": "2021-01-27T19:22:47.548+00:00",       positionsOccupancy {
    "groupId": 123,         "customId":
      ""       } groupId
       ]   } }

    createSubscriptionArea

    This mutation will create a new subscription area.

    Subscription Area Expiration

    By default, subscription areas expire 5 minutes after creation. Once a subscription area is expired, it cannot be extended and subscribers will stop receiving updates.

    Mutation

    Code Block
    languagegraphql
    mutation MyMutation { id
     createSubscriptionArea(     granularity: Group,   location {
     lat: 51.493930,      lon: -0.129030,   lat
      radius: 100   ) {     expiresOnlon
        granularity     id }
       location {      occupancyStatus
    lat       lon   statusChangeTime
     }     radius   } }
    

     

    Response

    Code Block
    languagejson
    {labels
       "data": {    }
    "createSubscriptionArea": {       "expiresOn": "2021-01-28T23:20:06.232+00:00",summary {
          "granularity": "Group",   undefined
       "id": 1,       total
      "location": {       occupied
     "lat": 51.49393,        available
    "lon": -0.12903       },
          "radius": 100}
        }
      }
    }

    onSubscriptionAreaUpdates

    This subscription will subscribe to occupancy updates inside an area.

    Selected updates object type must correspond to the granularity of the created search area:

    1. granularity: Position → updates { … on PositionOccupancy }

    2. granularity: Group → updates { … on GroupOccupancy }

    If you are unsure of the granularity for your subscription area, you can specify both types inside the updates.

    Subscription
    }
    

     

    Update

    Code Block
    languagegraphqljson
    subscription MySubscription{
      "data": {
      onSubscriptionAreaUpdates(id: 1) {  "onSubscriptionAreaUpdates": {
          "id": 1,
          "expiresOn": "2021-01-28T23:20:06.232+00:00",
           id"granularity": "Group",
        expiresOn  "location": {
     granularity     location { "lat": 51.49393,
        lat    "lon": -0.12903
     lon     },
          "radius": 1000,
          "updateTime": "2021-01-28T23:17:38.400+00:00",
          "updates": {
    [
         ... on GroupOccupancy {
            id  "id": 123,
         name     "name": "Foo",
      customId         location {"customId": null,
              "location": lat{
              lon  "lat": 51.493601937687224,
         }       "lon": -0.12852029611716095
    positionsOccupancy {         },
     customId         "positionsOccupancy": [
    groupId           id {
             location {    "customId": "",
           lat       "groupId": 123,
        lon           }"id": 1,
              occupancyStatus    "location": {
         statusChangeTime         }  "lat": 51.49360068522545,
         summary {           undefined"lon": -0.1286061268139623
              total    },
          occupied        "occupancyStatus": "Occupied",
     available         }    "statusChangeTime": "2021-01-28T23:17:38.400+00:00"
     }     }   } } 

     

    Update

    Code Block
    languagejson
    {   "datalabels": {
     null
      "onSubscriptionAreaUpdates": {       "id": 1, }
         "expiresOn": "2021-01-28T23:20:06.232+00:00",    ],
      "granularity": "Group",       "locationsummary": {
                "latundefined": 51.49393,0,
                "lontotal": -0.12903
    1,
         },       "radiusoccupied": 10001,
      
       "updateTime": "2021-01-28T23:17:38.400+00:00",         "updatesavailable": [ 0
              }
            }
        {  ]
        }
      }
    "id": 123,
        }
    

    updateSubscriptionArea

    This mutation will update an existing subscription area.

    Info

    All subscription area updates will extend expiration by 5 minutes from the current time.

    You can also send empty mutation to only update the expiration.

    Mutation

    Code Block
    languagegraphql
    mutation MyMutation {
      updateSubscriptionArea(
         "name"id: "Foo"1, 
             "customId"granularity: nullPosition, 
        radius: 500
       "location":) {
        expiresOn
        id
      "lat": 51.493601937687224, granularity
               "lon": -0.12852029611716095
              },
              "positionsOccupancy": [location {
          lat
          lon
     {   }
        radius
      }
    }
    

     

    Code Block
    languagegraphql
    mutation ExtendSubscription "customId": "",{
      updateSubscriptionArea(
        id: 1, 
      ) {
     "groupId": 123,  expiresOn
        id
      }
    }
    

    Response

    Code Block
    languagejson
    {
      "iddata": 1,{
           "updateSubscriptionArea": {
          "locationexpiresOn": {
    "2021-01-28T23:20:06.232134+00:00",
          "id": 1,
           "latgranularity": 51.49360068522545"Position",
          "location": {
            "lonlat": -0.1286061268139623
                  },
        51.49393,
             "occupancyStatuslon": "Occupied",-0.12903
          },
           "statusChangeTime": "2021-01-28T23:17:38.400+00:00"
          radius": 500
         }
      }
    }

    Code Block
    languagejson
    {
      "data": {
      

    ],

      "updateSubscriptionArea": 

    {
          "

    summary

    expiresOn": 

    {

    "2021-01-28T23:25:06.232134+00:00",
          "id": 1,
        

    "undefined": 0,

    }
      }
    }

    Use cases

    Query

    Use case

    Code Block
    languagegraphql
    query MyQuery {
      findGroupOccupancies(
        
    "total": 1
    lat: 0.0, 
        lon: 0.0, 
        
    "occupied"
    radius: 
    1,
    2000
      ) {
        location {
      
    "available":
      
    0
      lat
          lon
     
    }
       }
        summary 
    }
    {
          
    ]
    available
        }
      }
    }

    updateSubscriptionArea

    This mutation will update an existing subscription area.

    Info

    All subscription area updates will extend expiration by 5 minutes from the current time.

    You can also send empty mutation to only update the expiration.

    Mutation
    Info

    The summary object should be used to display availability for all parking group types

    Displaying all parking groups within 2km in a mobile app

    Image Added

    Code Block
    languagegraphql
    mutation
    query 
    MyMutation
    MyQuery {
      
    updateSubscriptionArea(
    findGroupOccupancies(zoneId: [1607]) {
        id
    :
    
      
    1,
      name
       
    granularity:
     
    Position,
    positionsOccupancy {
        
    radius:
     
    500
     occupancyStatus
     
    )
     
    {
        labels
    
    expiresOn
        }
    
    id
        summary 
    granularity
    {
        
    location
     
    {
     available
         
    lat
     occupied
         
    lon
     total
       
    }
       undefined
     
    radius
       }
    
    }  
      }
    }

    Getting group occupancy summary and each position status and labels to be able to calculate occupancy statistics by labels using only one query

    Code Block
    languagegraphql
    mutation
    query 
    ExtendSubscription
    MyQuery {
      
    updateSubscriptionArea
    groupOccupancy(
    id: 1
    ,
    ) {
        
    expiresOn
    positionsOccupancy {
       
    id
       
    } }

    Response

    Code Block
    languagejson
    location {
      
    "data":
     
    {
         
    "updateSubscriptionArea":
    lat
    
    {
           
    "expiresOn": "2021-01-28T23:20:06.232134+00:00",
     lon
          
    "id": 1,
    }
          occupancyStatus
    
    "granularity":
     
    "Position",
       }
      
    "location":
    }
    }

    Displaying individual parking positions when a user approaches his desired parking location

    Image Added
    Code Block
    languagegraphql
    query MyQuery {
      findPositionOccupancies(
        
    "
    lat
    "
    : 
    51
    0.
    49393
    0, 
        
    "
    lon
    "
    : 
    -
    0.
    12903
    0, 
        radius: 
    }
    2000,
        labels: 
    "radius": 500
    ['Disabled']
      ) {
      
    }
      id
    
    }
     
    } Code Block
    languagejson
    {
       
    "data":
    location {
     
    "updateSubscriptionArea":
     
    {
        lat
      
    "expiresOn":
     
    "2021-01-28T23:25:06.232134+00:00",
       lon
       
    "id": 1,
     }
        
    }

    Query

    Use case

    occupancyStatus
      }
    }

    Use cases

    Displaying occupancy statuses of positions with label “Disabled” within 2km radius

    Code Block
    languagegraphql
    query
    mutation 
    MyQuery
    MyMutation {
      
    findGroupOccupancies
    createSubscriptionArea(
        
    lat
    granularity: 
    0.0
    Position, 
        
    lon
    lat: 
    0
    1.
    0
    5, 
        
    radius: 2000 ) { location {
    lon: 1.5, 
        radius: 2000
    
    lat
      ) {
       
    lon
     id
      }
    }
    subscription 
    MySubscription 
    summary
    {
      onSubscriptionAreaUpdates(
      id: 
    available
    <id from previous mutation>
     
    }
     )
    
    }
    } InfoThe summary object should be used to display availability for all parking group types

    Displaying

    all

    live parking

    groups

    statuses within 2km

    in a mobile appImage Removed

    radius

    Code Block
    languagegraphql
    query MyQuery { groupOccupancy(id: 1) { positionsOccupancy {
    mutation LevelOccuppancyMutation {
      
    location
    createSubscriptionArea(
    
    {
        zoneId: 3, 
      
    lat
      granularity: Level
      ) {
     
    lon
       id
      }
    }
    subscription MySubscription {
      onSubscriptionAreaUpdates(
     
    occupancyStatus
     id: <id from previous 
    }
    mutation>
      
    }
    )
    }

    Displaying

    individual parking positions when a user approaches his desired parking locationImage Removed

    live occupancies per level in a zone (multistory car park)

    Image Added
    Code Block
    languagegraphql
    mutation 
    MyMutation
    LevelOccuppancyDisabledMutation {
      createSubscriptionArea(
        
    granularity
    zoneId: 
    Position
    3, 
        
    lat
    labels: 
    1.5
    "Disabled",
        
    lon
    granularity: 
    1.5, radius: 2000
    Level
      ) {
        id
      }
    }
    subscription MySubscription {
      onSubscriptionAreaUpdates(
      id: <id from previous mutation>
      )
    }

    Displaying live

    parking statuses within 2km radius

    occupancies of disabled spaces per level in a zone

    Image Added

    Code Block
    languagegraphql
    mutation MyMutation {
      updateSubscriptionArea(
        id: 1, 
      ) {
        expiresOn
        id
      }
    }

    Extend subscription area expiration

    Postman Collection

    Download Postman Collection here:

    View file
    nameGraphQL Occupancy.postman_collection.json

    Importing Collection

    1. Click import in My Workspace section.

    1. Upload the collection file and click

    Import.

    Adding API key to Postman Environment

    This collection uses the api_key variable to add an authorization token to the x-api-key header.

    1. To create a new environment click on the eye icon near the top right corner.

    2. Click Add to add a new environment.

    3. Add the gql_api_key variable name and your token in the initial value.

    4. Select the New Environment from the list.

    5. You can now test the requests in the GraphQL Occupancy Collection.

    Example Python Client

    There is a simple GraphQL client example in our Github repository. It is developed in Python and let you start getting data on demand and subscribe on occupancy change notifications.

    Please, follow the instructions in the README.md to prepare your invironment for running example.

    https://github.com/nwaveio/graphql_occupancy_example