Skip to content

C# Example

Below is a example of an integration of the ColonyCam Client written in C#. The example runs the following actions.

  • Initialise the ColonyCam
  • Open the drawer
  • Close the drawer
  • Take an image

Prerequisites

To test this example you should complete the following steps

  • Create a new console application in Visual Studio.
  • You will also need the server address of the ColonyCam.

The Code

The logic for invoking the endpoints has been separated into a dedicated ColonyCamClient class. Create a new class with this name and copy and paste the following code into it, ensuring that the DefaultAddress is corrected to match the server address listed in API Mode of the ColonyCam software

using System.Net;

namespace CSharpColonyCamClient
{
    /// <summary>
    /// Initializes a new instance of the ColonyCamClient class.
    /// </summary>
    /// <param name="baseAddress">The base IP Address and port.</param>
    public class ColonyCamClient(string baseAddress = ColonyCamClient.DefaultAddress) : IDisposable
    {
        #region Constants

        private const string DefaultAddress = "http://192.168.1.0:8080";
        private const string InitialiseEndpoint = "/v1/initialise";
        private const string OpenDrawerEndpoint = "/v1/open-drawer";
        private const string CloseDrawerEndpoint = "/v1/close-drawer";
        private const string ImageEndpoint = "/v1/image";

        #endregion

        #region Fields

        private HttpClient? client;

        #endregion

        #region Properties

        /// <summary>
        /// Get or set the base IP Address and port.
        /// </summary>
        public string BaseAddress { get; } = baseAddress;

        #endregion

        #region Methods

        /// <summary>
        /// Get an HTTP response from an API endpoint.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <param name="headerAcceptValue">The value for the accept header.</param>
        /// <returns>The HTTP response from the API endpoint.</returns>
        private async Task<HttpResponseMessage> GetResponse(string endpoint, string headerAcceptValue)
        {
            var response = new HttpResponseMessage();

            try
            {
                var address = $"{BaseAddress}{endpoint}";
                using (client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Clear();
                    client.DefaultRequestHeaders.Add("Accept", headerAcceptValue);

                    response = await client.GetAsync(address);
                }
            }
            catch (InvalidOperationException e)
            {
                response.StatusCode = HttpStatusCode.BadRequest;
                response.ReasonPhrase = $"Invalid operation: {e.Message}";
            }
            catch (HttpRequestException e)
            {
                response.StatusCode = HttpStatusCode.BadRequest;
                response.ReasonPhrase = $"Request error: {e.Message}";
            }
            catch (TaskCanceledException e)
            {
                response.StatusCode = HttpStatusCode.RequestTimeout;
                response.ReasonPhrase = $"Request timeout: {e.Message}";
            }
            catch (UriFormatException e)
            {
                response.StatusCode = HttpStatusCode.BadRequest;
                response.ReasonPhrase = $"Invalid URL format: {e.Message}";
            }
            catch (Exception e)
            {
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.ReasonPhrase = $"Unhandled error: {e.Message}";
            }

            return response;
        }

        /// <summary>
        /// Request  to initialise a ColonyCam.
        /// </summary>
        /// <returns>An HTTP response representing the result of the action.</returns>
        public async Task<HttpResponseMessage> RequestInitialiseAsync()
        {
            return await GetResponse(InitialiseEndpoint, "text/plain");
        }

        /// <summary>
        /// Request to open the drawer.
        /// </summary>
        /// <returns>An HTTP response representing the result of the action.</returns>
        public async Task<HttpResponseMessage> RequestOpenDrawerAsync()
        {
            return await GetResponse(OpenDrawerEndpoint, "text/plain");
        }

        /// <summary>
        /// Request to close the drawer.
        /// </summary>
        /// <returns>An HTTP response representing the result of the action.</returns>
        public async Task<HttpResponseMessage> RequestCloseDrawerAsync()
        {
            return await GetResponse(CloseDrawerEndpoint, "text/plain");
        }

        /// <summary>
        /// Request to get an image.
        /// </summary>
        /// <returns>An HTTP response representing the result of the action.</returns>
        public async Task<HttpResponseMessage?> RequestGetImageAsync()
        {
            return await GetResponse(ImageEndpoint, "application/octet-stream");
        }

        #endregion

        #region Implementation of IDisposable

        public void Dispose()
        {
            client?.Dispose();
        }

        #endregion
    }
}

Overwrite the contents of the Program.cs file with the following

using System.Net;
using CSharpColonyCamClient;

namespace Application;

class Program
{
    private static async Task Main()
    {
        var client = new ColonyCamClient();

        using (client)
        {
            // initialise ColonyCam
            var initialiseResponse = await client.RequestInitialiseAsync();
            var initialiseResponseContent = initialiseResponse.Content.ReadAsStringAsync().Result;
            Console.WriteLine($"Initialise status code: {initialiseResponse.StatusCode}");
            Console.WriteLine($"Initialise response: {initialiseResponseContent}");

            // open the drawer
            var openDrawerResponse = await client.RequestOpenDrawerAsync();
            var openDrawerResponseContent = openDrawerResponse.Content.ReadAsStringAsync().Result;
            Console.WriteLine($"Open drawer status code: {openDrawerResponse.StatusCode}");
            Console.WriteLine($"Open drawer response: {openDrawerResponseContent}");

            // close the drawer
            var closeDrawerResponse = await client.RequestCloseDrawerAsync();
            var closeDrawerResponseContent = closeDrawerResponse.Content.ReadAsStringAsync().Result;
            Console.WriteLine($"Close drawer status code: {closeDrawerResponse.StatusCode}");
            Console.WriteLine($"Close drawer response: {closeDrawerResponseContent}");

            // get the image
            var imageResponse = await client.RequestGetImageAsync();

            // save the image
            if (imageResponse?.StatusCode == HttpStatusCode.OK)
            {
                Console.WriteLine($"Take Image status code: {imageResponse.StatusCode}");
                Console.WriteLine("RequestGetImageAsync data received. Saving to file...");
                var bytes = await imageResponse.Content.ReadAsByteArrayAsync();
                await File.WriteAllBytesAsync("image.png", bytes);
                Console.WriteLine("RequestGetImageAsync saved as image.png");
            }
            else
            {
                var imageResponseContent = imageResponse?.Content.ReadAsStringAsync().Result;
                Console.WriteLine($"Image response: {imageResponseContent}");
            }
        }
    }
}

Run the program

Once finished, the console output should look like this

Example Client Console Output

Browse your file system to confirm that the image has been saved to the specified destination.