Commuty.ParkingAccess 2.5.5

dotnet add package Commuty.ParkingAccess --version 2.5.5
NuGet\Install-Package Commuty.ParkingAccess -Version 2.5.5
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Commuty.ParkingAccess" Version="2.5.5" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Commuty.ParkingAccess --version 2.5.5
#r "nuget: Commuty.ParkingAccess, 2.5.5"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Commuty.ParkingAccess as a Cake Addin
#addin nuget:?package=Commuty.ParkingAccess&version=2.5.5

// Install Commuty.ParkingAccess as a Cake Tool
#tool nuget:?package=Commuty.ParkingAccess&version=2.5.5

Commuty API - Parking Access

This package acts as a client to communicate with the Commuty Parking Access API. It avoids you to deal with HTTP direclty and provides you proper data structures to work with the API.

Supported features are:

  • Authenticate with Credentials
  • Verify a user can access a parking site
  • List all access rights for a day
  • Report who entered/exited the parking
  • Report a user that is known by the client but not by Commuty

Compatibility

This package is compatible with .NET Standard 1.1, which supports:

  • .NET Core >= 1.0
  • .NET Framework >= 4.5
  • Mono >= 4.6
  • Xamarin.iOS >= 10.0
  • Xamarin.Mac >= 3.0
  • Xamarin.Android >= 7.0
  • Windows Phone >= 8.1
  • Universal Windows Platform >= 10.0

Authentication

As an organisation, you must identify all your calls to the API using an Access Token. This token can be obtained by providing credentials (username/password) to a dedicated endpoint /token-requests.

Considering this token acquisition can take some time (up to 500ms), it should be kept in memory through multiple calls to the API (especially when using the functionnality "Verify a user can access a parking site", which requires a low latency). Each token is valid 24 hours.

Two types of clients

This package offers two types of clients, depending your constraints.

  • A Fluent Client that authenticates automatically, refreshes its authentication (when expired) and exposes the API functionnalities without security matters. This is the "easy way".
  • A Low Level Client that allows you to retrieve an access token and use it every time an API functionnality is called.

Which client fits best for you?

The type of client you need mostly depend whether you can keep your client instance in memory or not. If you can keep the client instance in memory through multiple calls to the API, then you should use the Fluent Client. However, if you want to use an access token manually (and keep it during multiple calls), you should use the Low Level Client.

Getting Started

First, add this package to your project as a dependency. Each class is exposed under the namespace Commuty.ParkingAccess.

FluentClient example in C# - List All Parking Access Rights

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToListAllAccessRights()
        {
            var client = ClientBuilder.Create()
                                      .WithCredentials("a-username", "a-password")
                                      .BuildFluentClient();

            // for example, you will list all access rights at midnight for today
            var allAccessRightsOfToday = await client.ListAllParkingAccessRights();

            // and at 8am, requesting new granted access rights for today
            var unreadOnly = true;
            var dryRun = false;
            var granted = true;
            var parkingSiteId = null;
            var includeAttributes = new List<AccessRightAttributeName>() { AccessRightAttributeName.Id, AccessRightAttributeName.Reason };
            var newAccessRightsOfToday = await client.ListAllParkingAccessRights(DateTime.Now, unreadOnly, dryRun, null, granted, parkingSiteId, includeAttributes);
        }
    }
}

FluentClient example in C# - Verify a user can access a parking site

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToVerifyAccessInRealTime()
        {
            var client = ClientBuilder.Create()
                                      .WithCredentials("a-username", "a-password")
                                      .BuildFluentClient();

            // each time a user scan its id at the parking entrance, for example
            var isAllowedToEnter = await client.VerifyAccess("a-parking-site-id", UserId.FromEmail("someone@your-company.com"));
            if (isAllowedToEnter)
            {
                OpenTheBarrier();
            }
            else
            {
                DoNotOpenTheBarrier();
            }
        }
    }
}

FluentClient example in C# - Report who entered/exited the parking

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToReportAccessLogs()
        {
            var client = ClientBuilder.Create()
                                      .WithCredentials("a-username", "a-password")
                                      .BuildFluentClient();

            // create a list of one or multiple accesses
            var accesses = new List<AccessLog>
            {
                AccessLog.CreateInAccessLog(UserId.FromEmail("someone@your-company.com"), new DateTime(2019, 10, 01, 08, 0, DateTimeKind.Utc)),
                AccessLog.CreateOutAccessLog(UserId.FromEmail("someone@your-company.com"), new DateTime(2019, 10, 01, 17, 0, DateTimeKind.Utc))
            };

            // send the accesses at regular interval (or send each access instantaneously)
            var savedAccessId = await client.ReportAccessLogs("a-parking-site-id", accesses);
            // you can save the 'savedAccessId' for future reference or simply discard it

        }
    }
}

FluentClient example in C# - Report a user that is known by the client but not by Commuty

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToReportAMissingUserId()
        {
            var client = ClientBuilder.Create()
                                      .WithCredentials("a-username", "a-password")
                                      .BuildFluentClient();

            // send every user that you know should be known to Commuty but isn't
            await client.ReportMissingUserId(UserId.FromBadgeNumber("444719"));
        }
    }
}

FluentClient example in C# - Report the number of available spots on a parking site

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToReportTheNumberOfAvailableSpots()
        {
            var client = ClientBuilder.Create()
                                      .WithCredentials("a-username", "a-password")
                                      .BuildFluentClient();

            var spotsThatAreAvailable = 55; // this is mandatory
            var totalSpotsOnTheSite = 101; // this can be null (int?)
            await client.ReportAvailableSpotCount("a-parking-site-id", spotsThatAreAvailable, totalSpotsOnTheSite);
        }
    }
}

LowLevelClient example in C# - List All Parking Access Rights

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToListAllAccessRights()
        {
            var client = ClientBuilder.Create()
                                      .BuildLowLevelClient();

            var accessToken = await client.Authenticate("a-username", "a-password");

            // for example, you will list all access rights at midnight for today
            var allAccessRightsOfToday = await client.ListAllParkingAccessRights(accessToken);

            // and at 8am, requesting new granted access rights for today
            try
            {
                var unreadOnly = true;
                var dryRun = false;
                var includeAttributes = new List<AccessRightAttributeName>() { AccessRightAttributeName.Id, AccessRightAttributeName.Reason };
                var granted = true;
                var parkingSiteId = null;
                var newAccessRightsOfToday = await client.ListAllParkingAccessRights(DateTime.Now, unreadOnly, dryRun, null, granted, parkingSiteId, includeAttributes, accessToken);
            }
            catch (WrongTokenException e)
            {
                // the token could expire in the meantime
                if (e.IsExpired()) {
                    accessToken = await client.Authenticate("a-username", "a-password");
                    var newAccessRightsOfToday = await client.ListAllParkingAccessRights(DateTime.Now, unreadOnly, dryRun, null, granted, parkingSiteId, includeAttributes, accessToken);
                }
                else
                {
                    throw e;
                }
            }
        }
    }
    
}

LowLevelClient example in C# - Verify a user can access a parking site

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToVerifyAccessInRealTime()
        {
            var client = ClientBuilder.Create()
                                      .BuildLowLevelClient();

            var accessToken = await client.Authenticate("a-username", "a-password");

            // each time a user scan its id at the parking entrance, for example
            try
            {
                var isAllowedToEnter = await client.VerifyAccess("a-parking-site-id", UserId.FromEmail("someone@your-company.com"), accessToken);
                if (isAllowedToEnter)
                {
                    OpenTheBarrier();
                }
                else
                {
                    DoNotOpenTheBarrier();
                } 
            }
            catch (WrongTokenException e)
            {
                // the token could expire in the meantime
                if (e.IsExpired())
                {
                    // refresh token
                }
                else
                {
                    throw e;
                }
            }
        }
    }
    
}

LowLevelClient example in C# - Report who entered/exited the parking

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToReportAccessLogs()
        {
            var client = ClientBuilder.Create()
                                      .BuildLowLevelClient();

            var accessToken = await client.Authenticate("a-username", "a-password");

            // create a list of one or multiple accesses
            var accesses = new List<AccessLog>
            {
                AccessLog.CreateInAccessLog(UserId.FromEmail("someone@your-company.com"), new DateTime(2019, 10, 01, 08, 0, DateTimeKind.Utc)),
                AccessLog.CreateOutAccessLog(UserId.FromEmail("someone@your-company.com"), new DateTime(2019, 10, 01, 17, 0, DateTimeKind.Utc))
            };

            try
            {
                // send the accesses at regular interval (or send each access instantaneously)
                var savedAccessId = await client.ReportAccessLogs("a-parking-site-id", accesses, accessToken);
                // you can save the 'savedAccessId' for future reference or simply discard it
            }
            catch (WrongTokenException e)
            {
                // the token could expire in the meantime
                if (e.IsExpired())
                {
                    // refresh token
                }
                else
                {
                    throw e;
                }
            }
        }
    }
}

LowLevelClient example in C# - Report a user that is known by the client but not by Commuty

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToReportAMissingUserId()
        {
            var client = ClientBuilder.Create()
                                      .BuildLowLevelClient();

            var accessToken = await client.Authenticate("a-username", "a-password");

            try
            {
                // send every user that you know should be known to Commuty but isn't
                await client.ReportMissingUserId(UserId.FromBadgeNumber("444719"), accessToken);
            }
            catch (WrongTokenException e)
            {
                // the token could expire in the meantime
                if (e.IsExpired())
                {
                    // refresh token
                }
                else
                {
                    throw e;
                }
            }
        }
    }
}

LowLevelClient example in C# - Report the number of available spots on a parking site

using System;
using System.Threading.Tasks;
using Commuty.ParkingAccess;

namespace Example
{
    class Test
    {
        async Task HowToReportTheNumberOfAvailableSpots()
        {
            var client = ClientBuilder.Create()
                                      .BuildLowLevelClient();

            var accessToken = await client.Authenticate("a-username", "a-password");

            try
            {
                var spotsThatAreAvailable = 55; // this is mandatory
                var totalSpotsOnTheSite = 101; // this can be null (int?)
                await client.ReportAvailableSpotCount("a-parking-site-id", spotsThatAreAvailable, totalSpotsOnTheSite, accessToken);
            }
            catch (WrongTokenException e)
            {
                // the token could expire in the meantime
                if (e.IsExpired())
                {
                    // refresh token
                }
                else
                {
                    throw e;
                }
            }
        }
    }
}

Using a proxy to access the API

Both LowLevelClient and FluentClient supports communication through a proxy. This proxy configuration must be an implementation of the interface System.Net.IWebProxy, such as System.Net.WebProxy.

var client = ClientBuilder.Create()
                          .WithProxy(new WebProxy("http://acme.com:1234", true))
                          .BuildLowLevelClient();

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.1 is compatible.  netstandard1.2 was computed.  netstandard1.3 was computed.  netstandard1.4 was computed.  netstandard1.5 was computed.  netstandard1.6 was computed.  netstandard2.0 was computed.  netstandard2.1 was computed. 
.NET Framework net45 was computed.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen30 was computed.  tizen40 was computed.  tizen60 was computed. 
Universal Windows Platform uap was computed.  uap10.0 was computed. 
Windows Phone wpa81 was computed. 
Windows Store netcore was computed.  netcore45 was computed.  netcore451 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.5.5 157 7/18/2023
2.5.4 132 7/5/2023
2.5.3 241 2/24/2023
2.5.2 237 2/14/2023
2.5.0 423 8/10/2022
2.3.2 385 10/22/2021
2.3.1 354 8/31/2021
2.3.0 408 7/30/2021
2.2.1 432 3/10/2021
2.1.4 470 10/12/2020
2.1.0 603 4/2/2020
2.0.1 631 1/8/2020
2.0.0 613 12/31/2019
0.7.0 784 3/19/2019
0.6.0 754 3/14/2019

0.2 - Supports Access Verification and Token Acquisition;
0.3 - Supports List of all Access Rights;
0.4 - Builder to create both FluentClient and LowLevelClient
0.5 - More documentation
0.6 - Use timezoned times
0.7 - Support communication through a Proxy
2.0.0 - Support for the version 2 of the API (report access log and missing ids)
2.1.0 - Support for counting available spots
2.1.4 - Support for wiegand and external ids
2.2.1 - Support for flags dryRun, createdAfter and includeAttributes on access-rights endpoint
2.3.0 - Support for flags parkingSpotId | parkingSpotName | parkingSpotDisplayName on of includeAttributes on access-rights endpoint. New endpoint to list all the parking spots of a given parking site.
2.3.1 - Support for UserIdType 'Access Code'
2.3.2 - Support for two License plate formats Wiegand26 (payload and FN+CN)
2.5.0 - Support for 'ForCarpoolersOnly' | 'ForDisabled' | 'Large' properties on Parking Spot
2.5.2 - Support for flag 'isVisitor' of includeAttributes on access-rights endpoint
2.5.3 - Support for flag 'granted' and 'parkingSiteId' on access-rights endpoint
2.5.4 - Added the value 'freeAccess' in the AccessRight's 'reason' property
2.5.5 - Support for flag 'subjectId' of includeAttributes on access-rights endpoint