ConveyOS PLC Communications - JSON

Introduction

Why JSON?

ConveyOS can talk to PLCs using industry standard Javascript Object Notation format, more commonly known as JSON. JSON has been widely adopted across the computing world, providing a straightforward way to serialize and deserialize messages in a self describing manner, without being overly verbose like XML. The leanness and simplicity of the format, bandwidth of modern networks, and built-in JSON parsing libraries available in nearly all modern programming languages make it a great option when exchanging data with PLCs. The PLC itself can generate JSON format messages with little extra overhead, and there is no need for complex custom formats that are neither self describing nor human readable.

JSON over TCP/IP

ConveyOS communicates with a PLC using TCP/IP sockets. ConveyOS acts as a client, while the PLC acts as a server.

Roles

sequenceDiagram
    autonumber
    participant ConveyOS as ConveyOS (Client)
    participant PLC as PLC (Server)<br/> 192.x.x.x:....
    par Sortation Messages
        PLC-->>ConveyOS: Scan JSON
        ConveyOS->>PLC: Assignment JSON
        PLC-->>ConveyOS: Divert JSON
    end
    autonumber off
    loop status + alarms
        PLC-->>ConveyOS: Section Status JSON
        PLC-->>ConveyOS: Alarm JSON
    end
    par 
        ConveyOS->>PLC: Section Command JSON
    end

PLC as Server

The PLC, acting as a TCP server should be readily available to connect to by any number of clients. An IP address and port should be provided as part of technical documentation for a specific customer solution. The PLCs ip address being provided by the customer based on network topology, and the port being provided by the PLC programmer.

ConveyOS as Client

ConveyOS will establish a connection to a PLC as a TCP client, using the IP addresses and ports provided in technical documentation for a specific customer solutuion. NOTE: ConveyOS does not require a fixed port to connect to or listen on, and can be configured and changed at any time as a customer project evolves.

Message Framing

Each complete message should be "framed" before sending. Framing and message terminators are not part of TCP/IP as a low level streaming protocol, so both the PLC and ConveyOS must determine when a complete new message begins and ends by using special characters that are placed just before and after the contents of a complete message. These characters "frame" the message much like a picture frame contains a painting - a frame isn't part of the picture, but is used to protect it and carry it from place to place. Framing tells ConveyOS - and the PLC - that it has received a complete message that it can do something with. Each message should be comprised of three parts:

<STX>

The beginning character must be the ASCII value 0x02 (decimal 2), also known as the STX (Start of Text) control character. This is a standard "non-printable" control character used when transmitting data. NOTE: This is a single character, not the string "0x02" or "STX" or "" or any derivative there-of. Because its considered a non-printable character, it gets referred to and displayed in different ways, but it should always be the a single character that converts to a decimal or hexidecimal value of 2.

JSON

The complete JSON formatted message should reside between the STX and ETX control characters. The message must start with an opening curly bracket { and end with a corresponding closing curly } bracket.

<ETX>

The final character after the actual JSON formatted message must be the ASCII value 0x03 (decimal 3), also known as the ETX (End of Text) control character. This is a standard "non-printable" control character used when transmitting data in low level protocols.

Framed Message Examples

STX                    JSON                                   ETX
\02{"msg":"scan","sorterId":1,"trackingId":3,barcode:"000123"}\03
STX          JSON                 ETX
\02{"msg":"full", "id": 1, "v": 1}\03

ConveyOS System Terminology

Layout / Map

A layout, or map, refers to the logical conveyor system, comprised of sections of conveyor and devices that are controlled by PLCs that ConveyOS interfaces with. A layout contains sorters to scan and divert cartons to lanes. Layouts typically contains one or more sorters, depending on complexity, and potentially hundred to thousands of unique sections.

Section

A section is an individually addressable and identifiable piece of A conveyor or component in a layout that is controlled by a PLC, and the PLC sends status updates for it to ConveyOS. Multiple sections define the flow and operations of a conveyor system - it is the primary building block of ConveyOS.

  • A section can have multiple different statuses that need to be tracked, a single value, or in some cases, nothing at all.

  • A section can be a single run of conveyor that has multiple different statuses, including if its running, how full it is, if its jammed, etc.

  • A section can also be a reference to a single motor or photo eye, anything that can be useful to a ConveyOS user to display, log, and report on real-time conditions of their conveyor system. A photo eye 'section' may have a single value - 1 or `0' describing it has being blocked or not, but there is no restriction that a section have only a single status. For instance, a section could be defined for a single motor that controls many other sections of conveyor. The PLC program should update the running status for all conveyor using that motor and send updates to ConveyOS for each affected section, but then the motor itself could also be a section with multiple statuses for its running state, its total run time, its current rpm/pulses, etc. The PLC can send updates when these values change, or at regular intervals depending on the nature of the inputs and how useful the data is to an end-user.

  • Sections that contain a barcode scanner or scan tunnel are referred to as inducts or scan points. They act as the starting point for how to get a carton from one point to another. The PLC receives the barcode data read by the scanner, assigns a tracking id so the cartons location can tracked on the span of conveyor by using a combination of photo eyes and timing based on current motor RPMs. The barcodes, tracking id, and an identifer of where the carton was scanned is sent in a Scan message to ConveyOS. Each induct section is given a unique Sorter Id used to identify it, and all its related destinations.

  • A section that is a destination that a carton can divert or transfer to is referred to as a lane. Each lane is given special configuration in ConveyOS to tell it what sorter it belongs to based on its Sorter Id. Lanes require multiple statuses from a PLC that aren't required for in-between 'transport' conveyor:

    • Is it enabled, as in, are cartons allowed to divert to this section?

    • How full is the lane? Based on the number of photo eyes spaced equally along the lane, it is possible to determine what percentage of the lane is occupied by the PLC checking how long these photo eyes are blocked and in what sequence. The PLC should then send a status message with the current full percentage as a whole number between 0 and 100. The number of possible values for the percentage are dictated by the number of photo eyes on the lane. If a photo eye only exists at the very entrance of a lane, then the PLC can only report that the lane is either empty (0) or full (100). If there are 2 photo eyes, then its possible to do 0, 50, or 100. When three are present, its possible to send updates based on 25 percent increments, and so on. This full value can be used by the PLC program, as well as ConveyOS, to distribute cartons to less utilized lanes to optimize productivity as well as limit potential jams and sorter gridlock.

Sorter

Lane

Reject

Data Type Mapping

JSON only as a few primitive data types - due to it being born from Javascript which is primarily a dynamically typed language meant to run in web browsers where RAM is ample and desktop computers have more than enough power to spare - where being loose with data is a good trade-off for developer productivity. Most PLCs, on the other hand, use strict typing. Memory is limited, and how you store that data and process that memory is critical.

Numbers

  • PLCs specify the length and range of of numbers in bits, bytes, words, double words, with signed and unsigned versions of each. The data type names can vary slightly from PLC vendor to PLC vendor, but the concepts are the same.

  • Javascript/JSON simply uses number, this is used to represent both floating point and whole numbers. Numbers in JSON are unquoted:

{
    "some_number": 123,
    "another_number": 1.0,
    "floating_point": 3.14159,
    "not_a_number": "12353". <-- A string containing numbers
}

ConveyOS does not explicitly care about the internal data typing used in a PLC when communicating via JSON. A PLC programmer is free to use the most appropriate data type for the task at hand provided by their particular PLCs programming languages - as long as it can contain the range of numbers necessary for the property being sent via JSON to map to the correct values used in ConveyOS.

While JSON has dynamic typing, the ConveyOS back-end and database are not Javascript, and are strictly typed. When parsing / deserializing the JSON messages, the number property values must reflect the primitive type used for a property on the back-end, eg: if a value from the JSON is a floating point number, but ConveyOS expects a whole integer, the data conversion will fail and the message would be thrown out, causing inconsistencies between the PLC and ConveyOS as to the status of the conveyor system as well as possibly causing cartons to be rejected, and the sky to fall.

Numbers as unique identifiers

ConveyOS uses whole numbers as unique identifiers for PLC addressable sections of the system (conveyor, photo eyes, motors, etc) as well as for logical constructs like sorters and alarms.

  • Sorters Ids: 1 to 255 - each id represents a single logical sorter in the system where a carton can be scanned and an assignment and divert will occur. Typically, ids start low and increment in the direction of flow of the conveyor. Most conveyor systems have well below 255 different points where branching can occur, so storing them internally in the PLC program as a single unsigned Byte is possible, but not required if a larger data type is preferred.

  • Section Ids: 1 to ??? - each id represents a uniquely identifiable section of conveyor, photo eye, or some other component that the PLC monitors the inputs and may change the outputs of. Any message that gets sent to ConveyOS about a particular section must also send the id of that section.

    • Section ids do not need to be contiguous. Skipping numbers may actually be preferrable if it's anticipated that a system will grow and have new sections placed in between existing.

    • Section ids can be numbers with 'meaning'. If parts of the system are labelled with unique numbers on mechanical or electrical drawings/blueprints, it makes sense to carry those numbers forward in to the program as well as use them in ConveyOS for clearer tracability, For example, if a section of conveyor is addressed on a drawing as "111000", then using the id as 111000 is a logical choice. If there is a complex numbering or labeling scheme on a drawing that doesn't directly map to whole numbers, eg: 1.4.A.0, then it's up to the PLC programmer, conveyor engineers, and ConveyOS engineers to determine whaßt numbering pattern to agree on and use.

    • It is recommended to store/reference them in the PLC program, if necessary, as unsigned integers / double words (32 bits) in the PLC program to give a range from 1 to 4,294,967,295. This gives flexibility in using long numbers when providing meaning to the identifers as mentioned in the previous bullet point.

    • A technical document listing out what section id corresponds to what system component for a customer implementation is always required. This data is used throughout ConveyOS for nearly everything. At a minimum, the document should provide a complete list of sections, preferablly in excel or CSV, with three columns:

      • section id - the unique id of the section/component as a whole number
      • name - a brief label / short name for the section: eg "#1234" or "PE2.3"
      • description - a longer name without any acronyms or shortened technical / industry jargon that can help operators understand the purpose and location of the component: eg: "Accumulation Conveyor #1234" or "Photo Eye 2.3 for Conveyor #1234".
  • Lane Numbers: 1 to 99 per sorter - Each logicl sorter in a ConveyOS system has 1 or more physical destination / sections it diverts cartons to. These can be referred to at each sorter simply as lanes. Each lane at each sorter is given a number.

    • For mult-lane sorters

      Typically starting at 1, going from closest divert after a scanner, to the furthest away. The value 99 is a special value reserved for sending cartons to a designated reject or recirc loop.

    • For transfers

      For "H" transfers typically found in pick modules where cartons can be moved from one side of a pick mod to the other, the lane numbers designate which direction the carton should move in, from the point of view of the carton when it is scanned:

      1 = move left.

      2 = move right.

      99 = go straight.

    • Special induction points

      For scanners / induction points that don't have any branching for some reason, such as an induction point that needs interact with a customers WMS prior to any further downstream processing, a value of 1 will suffice.

Boolean, on/off, true/false = 1 or 0

While JSON can use unquoted values of true and false and most JSON parsers will then convert it to the calling programming languages boolean/bit type, ConveyOS simply uses 1 and 0. This makes it easier to build JSON messages on the PLC, and saves a little bit of processing and network bandwidth to boot. In addition, it reduces the number of different message "shapes" necessary for sending conveyor section status updates, as all values are integers. It also allows for easier modification if values of 1 and 0 no longer suffice to represent some state.

The PLC program (and programmer) is free to use the smallest data type available, such as a bit or boolean, but there is no requirement from ConveyOS to do so. If it makes sense to use a full byte to represent 255 potential values for future expansion, or a larger data type, it does not matter, as long as the value in the JSON output is either '1' or '0':

{
    "is_on": 1,
    "is_off": 0,
}

1 should represent on, active, enabled, true, blocked, triggered, yes, running, energized - you get the point.

0 should represent the opposite: off, inactive, disabled, false, waiting, no, not running, stopped, no power, etc, etc.

Sortation Messages

A grouping of a scanner / induction point and one or more downstream destinations on a conveyor system is referred to as a Sorter in ConveyOS. A Sorter can be an actual sorter with multiple lanes, a transfer in a pick mod, or a single induction point with a straight path forward. In each case, there is always:

  • An entry point with a scanner where barcode data can be sent to a PLC for whatever was scanned. That data is then married with a unique number identifying the sorter, as well as unique tracking id for the scanned carton. This data is sent to ConveyOS. This is referred to as a Scan message.

  • ConveyOS processes the Scan message and determines where the carton should go. It sends back an Assignment message to the PLC, requesting it to diver the carton to a paticular lane (or set of lanes).

  • The PLC attempts to honor the Assignment based on the status of the downstream lanes, based on the full status, enabled state, and any active alarms that should prevent the lane from being used.

    • If the first lane requested in an assignment isn't currently available, and alternate lanes are provided in the message, the PLC should attempt to use them in the order they are provided. If no requested lane is available, the PLC should then:

      • If the sorter has a dedicated reject lane, divert the carton there.
      • If the sorter doesn't have a reject lane, or it is unavailble, but there is an exit to a recirculation loop, divert the carton to the entrance of the loop.
      • If there is neither an available reject lane, or a recirulation exit, then the carton is in a no-win scenario where the conveyor, depending on the design, could quickly fill up.

The PLC always has the final say, since it always has the most up to date information, where as the request for an assignment from ConveyOS can be outdated due to latency and movement of the carton along the conveyor. Once the carton has reached its intended (or not intended) destination, the PLC sends back a Diverted message, giving the outcome of the Assignment request and where the carton really went, and why.

Scan

Sent from a PLC to ConveyOS

{
    "msg": "scan",
    "sorterId":1,
    "trackingId": 1,
    "barcode": "abc1235000123355",
    "barcode2": "sku1234",
    "barcode3": "...",
    "barcode4": "...",
    "barcode5": "..."
}

When a barcode is scanned at a sorter, transfer, or other induction point, a message with the pertinent details of the scan and where it took place should be sent.

Properties

  • msg - text: the type of message being sent, the value should always be "scan".

  • sorterId - number: the id of the logical sorter where the scan ocurred.

  • trackingId - number: the unique number assigned to the scanned carton/tote used to track its location from the scan point to when it diverts.

    • The inclusion of the tracking id is necessary to differentiate between cartons that may have the same barcodes, but are in fact different physical containers.

    • The tracking number should be unique per scan. The most common way to handle this in a PLC program is to increment a single integer after every scan, and once a upper limit is reached, reset the value back to 0. For example, a sorter could have tracking ids in the range of 0 - 250.

    • The same tracking number one after another at the same sorter id will be handled as an update to the previously sent scan message.

  • barcode - text: the primary barcode scanned on a label, the one that is to be used as the primary barcode when searching for a matching carton in COS. This field is always required.

  • barcode2 - barcode5 - text: ConveyOS supports up to 5 barcodes for a single scan, not all customer solutions require this many (only the barcode property is absolutely required):

    • If a customer solution needs additional barcodes to be scanned beyond the primary: the PLC program should pass the 2nd barcode as barcode2, and if a 3rd is needed, it should be passed as barcode3 and so on. It is expected for any barcode beyond the primary to always use the "same slot" - do not sometimes use barcode2 and sometimes barcode3. If the customer solution requires variable scanning where there can be cartons that contain 1 or more barcodes, always supply the other barcode properties up to the total possible amount. If a barcode isn't applicable to a particular carton/scanning scenario, then provide the value as an empty string (""). In scenarios where multiple barcodes are expected, follow the same rule that applies to primary barcodes when a no read occurs.

    • If only a single barcode is required: It is not required to send empty strings or NULL fields if these properties won't be used, simply omit them from the message.

No Reads

If the scanner could not read a barcode, the PLC should set the barcode to be a series of two or more question marks, one after another:

{
    "msg": "scan",
    "sorterId":1,
    "trackingId":2,
    "barcode": "???"
}

Multi-Reads

If the scanner attempted to read multiple barcodes at once and cannot determine which to provide, this is referred to as a multi-read. The scanner will most likely send a series of exclamation marks to the PLC. These should be provided in the barcode field in the scan message:

{
    "msg": "scan",
    "sorterId": 1,
    "trackingId":100,
    "barcode": "!!!"
}

Assign

In response to a Scan message sent from the PLC to ConveyOS, ConveyOS will determine where the carton should go, and then reply with an assignment message asking the PLC to assign a carton to a specific lane or lanes:

Single lane assignment

{
    msg: "assign",
    sorterId: 1,
    trackingId: 100,
    lane: 1
}

Multiple lane assignment

When there are other potential lanes that could be used if the primary lane is unavailable (according to the PLC), or the PLC itself is handling round-robin logic, multiple lane numbers can be sent to the PLC with an additional property, alt. If the alt property is present and

{
    msg: "assign",
    sorterId: 1,
    trackingId: 100,
    lane: 1
    alt: [2,5,99]
}

Divert

{
    msg: "divert",
    sorterId: 1,
    trackingId: 100,
    lane: 1,
    rc: 1
}

Section Status

{
    msg: "status",
    id: 123,
    t: 1,
    v: 1
}

Status types

The value passed in the t property determines what status is being reporting from the PLC for a particular section. A section can have multiple different statuses, but a single message shape is used to cover all of them. When a value changes in the PLC, a status message should be sent to ConveyOS for the affected section and status that changed.

  • jammed - 1 or 0
  • photo-eye - 1 or 0
  • enabled - 1 or 0
  • running - 1 or 0
  • full - 0 to 100
  • merge-release - 1 or 0
  • merge-lane-count - number

Alarms

{
    msg: "alarm",
    id: 1,
    v: 1
}
  • msg - message type of "alarm"
  • id - unique identifier for the alarm
  • v - 1 for active, 0 for inactive