Skip to main content

PackNet Online Documentation

Code Samples

ImportData Endpoint Examples

The following headers have been added and mapped to the configuration: JobTitle, ProductionGroup, Length, Width, Height, DesignID, CustomAttribute1, and CustomAtribute2

[
    {
    "JobTitle": "ImpoprtDataExample_0001",
    "ProductionGroup": "EM Basic",
    "Length": "7",
    "Width": "6",
    "Height": "5",
    "DesignId": "2010001",
    "CustomAttribute1": "Value1",
    "CustomAttribute2": "Value2"
    }
]
[
    {
    "JobTitle": "ImpoprtDataExample_0001",
    "ProductionGroup": "EM Basic",
    "Length": "7",
    "Width": "6",
    "Height": "5",
    "DesignId": "2010001",
    "CustomAttribute1": "Value1",
    "CustomAttribute2": "Value2"
    },
{
    "JobTitle": "ImpoprtDataExample_0002",
    "ProductionGroup": "EM Basic",
    "Length": "7.5",
    "Width": "4.4",
    "Height": "8",
    "DesignId": "2010001",
    "CustomAttribute1": "Value1",
    "CustomAttribute2": "Value2"
    }
]

Sample AMQP Code

Packsize users can use the following code to build a basic AMQP message the consumer receives the Event Notifications from Packsize. This code is intended to be a very basic example and is written in C#.

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;

// RabbitMQ server connection parameters
var factory = new ConnectionFactory() { HostName = "localhost" }; // Update with your RabbitMQ server details

// Create a connection and a channel
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
    string exchangeName = "PackNetNotifications";
    // Declare the Exchange that will receive the Packsize Event Notifications
    channel.ExchangeDeclare(exchangeName, ExchangeType.Topic, true);

    // Declare the queue to consume from
    string queueName = "ENQueue";
    channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);
    //Bind the queue to receive messages from the exchange. This will bind to ALL possible routing keys.
    channel.QueueBind(queueName, exchangeName, "Imported");
    channel.QueueBind(queueName, exchangeName, "ImportFailedStatus");
    channel.QueueBind(queueName, exchangeName, "ImportedStatus");
    channel.QueueBind(queueName, exchangeName, "StagedStatus");
    channel.QueueBind(queueName, exchangeName, "StagingFailedStatus");
    channel.QueueBind(queueName, exchangeName, "SelectedStatus");
    channel.QueueBind(queueName, exchangeName, "MachineGroupStatus");

    // Set up the consumer
    var consumer = new EventingBasicConsumer(channel);

    // Define what to do when a message is received
    consumer.Received += (model, eventArgs) =>
    {
        var body = eventArgs.Body;
        var message = Encoding.UTF8.GetString(body.ToArray());

        Console.WriteLine($"Received message: {message}");
    };

    // Start consuming messages
    channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);

    Console.WriteLine("Press [Enter] to exit.");
    Console.ReadLine();
}

Sample Webhook Code with HMAC Verification

A Packsize user can use the follow code to build a basic webhook that authenticates the request using a known secret, this code is intended to be a very basic example and is written in C#.

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;

namespace WebhookSample.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class SampleWebhookController : ControllerBase
    {
        private static readonly string _secretKey = "SOME_SECRET_KEY";

        private readonly ILogger<SampleWebhookController> _logger;

        public SampleWebhookController(ILogger<SampleWebhookController> logger)
        {
            _logger = logger;
        }

        [HttpPost]
        public async Task Post([FromBody] string payload, [FromHeader(Name = "x-packsize-signature")] string receivedSignature)
        {
            try
            {
                if (IsSignatureValid(payload, _secretKey, receivedSignature))
                {
                    // Signature is valid, process the webhook payload {x-packsize-signature: SOME_SIGNATURE}
                    HttpContext.Response.StatusCode = 200;
                    await HttpContext.Response.WriteAsync("Webhook received and processed successfully.");
                }
                else
                {
                    // Invalid signature, reject the request
                    HttpContext.Response.StatusCode = 401;
                    await HttpContext.Response.WriteAsync("Invalid signature");
                }
            }catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to process webhook request due to {error}", ex.Message);
                throw;
            }
        }

        private bool IsSignatureValid(string payload, string secretKey, string receivedSignature)
        {
            byte[] keyBytes = Encoding.ASCII.GetBytes(secretKey);
            byte[] payloadBytes = Encoding.ASCII.GetBytes(payload);

            using (var hmac = new HMACSHA256(keyBytes))
            {
                byte[] hashBytes = hmac.ComputeHash(payloadBytes);
                string computedSignature = Convert.ToBase64String(hashBytes);

                return receivedSignature == computedSignature;
            }
        }
    }
}

Event Notification Examples

Packaging Solution Status Message Examples

Below is the JSON Structure and examples of Packaging Solution Status Messages.

cycleTime is not the same as Throughput

Please note in the examples below that "cycleTime" is not equivalent to throughput.

Failure reasons are omitted when they are null

Please keep in mind that failureReason, productionData.failureReason, and location.packStation will be omitted when they are null.

{
  "eventUtcTimeStamp" : ISO 8601 DateTime,
  "messageId" : GUID,
  "internalUniqueId": GUID,
  "batchId": GUID,
  "groupIdDate": ISO 8601 DateTime,
  "alias": string,
  "status": string,
  "licensePlateNumber": string,
  "cartons":
  [
    {
      "media":
      {
        "dimensions":
        {
          "length": double,
          "width": double,
          "height": double
        },
        "thickness": double,
        "style": GUID,
        "brand": string,
        "cost": double,
        "attributes": dictionary<string, string>
      },
      "cost": double,
      "requiredTimeToPack": TimeSpan,
      "contents":
      [
        {
          "dimensions":
          {
            "length": double,
            "width": double,
            "height": double
          },
          "weight": double,
          "fragility": string,
          "identifier": string,
          "attributes": dictionary<string, string>
        }
      ],
      "prints":
      [
        {
          "placement":
          {
            "x": double,
            "y": double
          },
          "dimensions":
          {
            "length": double,
            "width": double,
            "height": double
          },
          "rotation": double,
          "layer": int,
          "cost": double,
          "value": string,
          "requiredTimeToPack": TimeSpan,
          "attributes": dictionary<string, string>
        }
      ],
      "labels": [See labels below],
      "rotation": GUID,
      "additionalDimensions":dictionary<string, double>,
      "attributes":dictionary<string, string>,
      "productionData":
      {
        "machineGroup": string,
        "orientation" : GUID,
        "tileCount" : int,
        "machine" : string,
        "materialUsage" : 
        {
          "alias": string,
          "width": double,
          "thickness": double,
          "brand": string,
          "usedWidth" : double,
          "builtInWasteWidth" : double,
          "trimWidth" : double,
          "usedLength" : double
        },
        "optimal" : bool,
        "cycleTime" : TimeSpan,
        "failureReason" : string,
        "waitingTime" : TimeSpan,
        "barcode" : GUID,
        "flapsDown" : bool,
        "flapsDownBandUsed" : double
      }
    }
  ],
  "labels":
  [
    {
      "placement":
      {
        "x": double,
        "y": double
      },
      "media":
      {
        "dimensions":
        {
          "length": double,
          "width": double,
          "height": double
        },
        "thickness": double,
        "style": string,
        "brand": string,
        "cost": double,
        "attributes": dictionary<string, string>
      },
      "cost": double,
      "verificationCode": string,
      "requiredTimeToPack": TimeSpan,
      "attributes": dictionary<string, string>
    }
  ],
  "importDate": ISO 8601 DateTime,
  "createByDate": ISO 8601 DateTime,
  "releasedForProductionDate": ISO 8601 DateTime,
  "priority": int,
  "cartonPropertyGroups": [string],
  "classification": string,
  "estimatedTotalCost": double,
  "estimatedTimeToPack": TimeSpan,
  "contentWeight": double,
  "location":
  {
    "productionGroup": string,
    "machineGroup": string,
    "machine": string,
    "packstation": string,
    "pickZone": string
  },
  "attributes": dictionary<string, string>,
  "options":
  {
    "prioritizeProductionBy": string, 
    "maxFailedProductionRetries": int
  },
  "failureReason": string
}
{
  "eventUtcTimeStamp" : "2023-05-07T21:29:01.8886462Z",
  "messageId" : "ee63ccf2-fc1a-43f7-b892-44f0415aca07",
  "internalUniqueId": "227fbf09-566f-4958-bc4d-c9eac741036d",
  "batchId": "327fbf09-566f-4958-bc4d-c9eac741036d",
  "groupIdDate": "2023-05-05T18:18:10.4389866Z",
  "alias": "Name from customer",
  "status": "Imported",
  "licensePlateNumber": "Unique id from customer",
  "cartons":
  [
    {
      "media":
      {
        "dimensions":
        {
          "length": 23.5,
          "width": 10.25,
          "height": 3.75
        },
        "thickness": 0.12,
        "style": "201",
        "brand": "empty or name of required branding of material",
        "cost": 4.56,
        "attributes":
        {
          "mediaRelatedCustomerTag1": "customer's value"
        }
      },
      "cost": 3.45,
      "requiredTimeToPack": "01:23:45.67",
      "contents":
      [
        {
          "dimensions":
          {
            "length": 7.5,
            "width": 8.25,
            "height": 2.75
          },
          "weight": 23.45,
          "fragility": "",
          "identifier": "Customer Identifier such as UPS/EAN/IBAN",
          "attributes":
          {
            "contentRelatedCustomerTag1": "customer's value"
          }
        }
      ],
      "prints":
      [
        {
          "placement":
          {
            "x": 12.2,
            "y": 3.75
          },
          "dimensions":
          {
            "length": 24.5,
            "width": 12.25,
            "height": 0
          },
          "rotation": 37.5,
          "layer": 1,
          "cost": 345.67,
          "value": "PrintImageName",
          "requiredTimeToPack": "01:23:45.67",
          "attributes":
          {
            "printRelatedCustomerTag1": "customer's value"
          }
        }
      ],
      "labels": [See labels below],
      "rotation": "270F",
      "additionalDimensions":
      {
        "x1": 1.25
      },
      "attributes":
      {
        "cartonRelatedCustomerTag1": "customer's value"
      },
      "productionData":
      {
        "machineGroup": "Machine Group Alias",
        "orientation" : "270F",
        "tileCount" : 1,
        "machine" : "Machine Alias",
        "materialUsage" : 
        {
          "alias": "Corrugate Alias",
          "width": 20.125,
          "thickness": 0.158,
          "brand": "MyBrand",
          "usedWidth" : 423.2,
          "builtInWasteWidth" : 76.8,
          "trimWidth" : 49.9,
          "usedLength" : 823.9
        },
        "optimal" : true,
        "cycleTime" : "00:00:18.0100000",
        "failureReason" : "Retracted",
        "waitingTime" : "00:00:00",
        "barcode" : "42530858",
        "flapsDown" : false,
        "flapsDownBandUsed" : 42.6
      }
    }
  ],
  "labels":
  [
    {
      "placement":
      {
        "x": 12.2,
        "y": 3.75
      },
      "media":
      {
        "dimensions":
        {
          "length": 6,
          "width": 4,
          "height": 0
        },
        "thickness": 0.01,
        "style": "4x6",
        "brand": "empty or name of required branding of material",
        "cost": 6.78,
        "attributes":
        {
          "mediaRelatedCustomerTag1": "customer's value"
        }
      },
      "cost": 3.45,
      "verificationCode": "Barcode/QR code",
      "requiredTimeToPack": "01:23:45.67",
      "attributes":
      {
        "labelRelatedCustomerTag1": "customer's value" 
      }
    }
  ],
  "importDate": "2023-05-05T18:18:10.4389866Z",
  "createByDate": "2023-05-05T19:18:10.4389866Z",
  "releasedForProductionDate": "2023-05-05T18:28:10.4389866Z",
  "priority": 1,
  "cartonPropertyGroups": ["cpg1", "cpg2"],
  "classification": "eaa",
  "estimatedTotalCost": 12.34,
  "estimatedTimeToPack": "01:23:45.67",
  "contentWeight": 23.45,
  "location":
  {
    "productionGroup": "PG1",
    "machineGroup": "MG1",
    "machine": "M1",
    "packstation": "ps1",
    "pickZone": "PZ1"
  },
  "attributes":
  {
    "packagingSolutionRelatedCustomerTag1": "customer's value"
  },
  "options":
  {
    "prioritizeProductionBy": "MaterialUsage", 
    "maxFailedProductionRetries": 3
  },
  "failureReason": "Could not map incoming data"
}
Machine Group Status Message Examples

Below is the JSON Structure and examples of the Machine Group Status Messages.

{
    "eventUtcTimeStamp": "ISO 8601 DateTime",
    "machineGroup": "String",
    "productionEnabled": "Boolean",
    "status": "String"
}
{
    "eventUtcTimeStamp": "2023-03-27T22:22:59.6041811Z",
    "machineGroup": "X5-01-MG",
    "productionEnabled": true
    "status": "Online"
}