Adding Machine Analytics Support to New Printers

This document is designed to assist printer manufacturers in the steps necessary to add native support for Authentise Machine Analytics to their printers. The goal is to allow the printer to be connected through a network to a computer that can harvest status information about the printer on an ongoing basis. This data can then be used to make high-level decisions around inventory management, capacity planning, and maintenance.

Authentise Machine Analytics harvests data from printers using a program called Echo. Echo speaks many protocols natively to accomodate different printers. Printers with built-in support for Echo communicate via HTTP over TCP/IP on port 80. The printer should start a web server internally after startup that is able to service HTTP requests on port 80. Data transferred via HTTP should be formatted as JSON.

GET /status/

There are two endpoints that the printer should support. The first is a status endpoint which responds to an HTTP request with the path /status/. This endpoint returns the current status information of the printer. It should respond with all of the following properties contains within a JSON object

Properties returned on GET /status/
Property Name Property Type Description
current_build object An object containing information about the current build if any, otherwise ‘null’
current_build.estimated_end_time string (ISO 8601 datetime in UTC timezone) The date and time and timezone when the current build is estimated to complete
current_build.id string A programmatically generated unique ID for the current build. This should ideally be a UUID
current_build.name string The user-supplied name of the current build
current_build.percent_completed float A number from 0.0 to 100.0 indicating the amount of the total material for the build has been consumed
current_build.start_time string (ISO 8601 datetime in UTC timezone) The date and time and timezone when the current build started
errors array An array of short strings that identify any error states for the printer
errors.N.code string A short string meant to be a stable, machine-readable indicator of the type of error
errors.N.detail string (may be localized) A long-form explanation of the error and possible remedies the user could use
materials array An array of objects detailing the materials that are loaded into the printer
materials.N.expiration string (ISO8601 datetime in UTC timezone) The date when the material will expire, if any. Otherwise ‘null’
materials.N.id string A unique identifier for this particular material type
materials.N.quantity float The quantity of the material available in whatever units are supplied
materials.N.units string The unit of measure used to determine quantity
online_since string (ISO 8601 datetime in UTC timezone) The date and time and timezone when the printer came online
sensors array An array of objects detailing current sensor states
sensors.N.name string The name of the sensor
sensors.N.taken string (ISO 8601 datetime in UTC timezone) The date, time, and timezone the sensore reading was recorded or taken
sensors.N.units string The units used in the sensor
sensors.N.value string/float/boolean/integer The value of the sensor
status string The current status of the printer (printing, idle, warming, preparing, error, etc)

current_build

The current build property should be set to null if the printer is not currently printing or building any parts. Otherwise it should be set to an object with the following properties

current_build.estimated_end_time

The estimated_end_time property should be a date and time when the machine currently estimates that the build should complete. No particular algorithm for estimation is implied or required and the estimate can be calculated to service each request or it can be calculated once and stored. For processes that require curing, cooldown or other “ramping-down” processes this estimate should include the time for ramp-down. The estimate should target the first moment when a technician could safely remove the completed build from the printer.

current_build.id

The id property for the current build should be a globally unique identifier. In other words, the ID should not conflict between two printers of the same model installed in the same location. For this reason they should be automatically generated via software. It is strongly recommended that a standards-compliant UUID be used for this purpose. This value will be used to uniquely identify two build that happened on the same printer with the same parameters using the same input data that happened at different times.

current_build.name

The name property should be the user-supplied name for the build. This value may be duplicated between builds on the same or different printers. The user should have been given some opportunity to control the name at some point during the preparation of the build. If not, this value can be null

current_build.percent_completed

The percent_completed value is designed to give the user a sense of how much material has been consumed towards completing the build. For some printers this value may be quite different from the estimated_end_time. For example, if a particular printer tends to use most material in the initial stages of the print then the percent_completed may be well over %50 when most than half the time remains between the start_time and estimated_end_time.

This property can be very useful for a technician to make decisions such as whether or not to fill supply hoppers or spools with additional raw materials or whether or not to abort a particular build part of the way through the process

current_build.start_time

This is the start date and time when the build was initiated. This is not the time when the user requested the build. It may not be the same time as when the first material was deposited for the build. It should be considered the first moment when the machine began the process of performing the build. For processes that require a warming period the time should begin when warming began.

errors

The errors array should contain zero or more items indicating errors the system may be having. If the printer is functioning well and has no errors this value should be [] rather than null. This property contains an array so that a printer may report multiple simultaneous errors to a client. Each error should be a short JSON object which contains the following properties

errors.N.code

This is a machine-readable code that is meant to be a stable way to indicate an error type. For example, a motor could have failed on the printer. An appropriate code for this may be motor-failure. This is a stable, meaningful value that is non-localized and generic. These values should not be translated into other languages.

errors.N.detail

This is a human-readable detailed message that is meant to assist users in understanding the detail of an error and what they might be able to do to solve the problem, if anything. For example, a motor could have failed on the printer. An appropriate code for this may be motor-failure. An appropriate detail value to go with that code could be Motor #5 has overheated. Wait one hour before proceeding to fully cool to avoid damage to the motor. This information could also be translated into other languages.

materials

The materials property contains information, if available, about the materials that are loaded and available to the printer. In situations where the printer cannot know about its own materials this property should be set to null. In situations where the printer does know about its own materials but there are none loaded or available this value should be []. This property is a list so that different printers that track or use varying amounts of materials can track as many materials as is appropriate for their process. Each element in the materials array should be a JSON object with the following properties

materials.N.expiration

The date and time and timezone when the material is expected to expire. This may be a good-faith best estimate of an exact time or may set an amount of precision by setting other parts of the date and time to zero. For example, if expiration is expected to happen at some time in the month of October then value could be 2017-10-00T00:00:00.000+000. If the material is not expected to expire or the expiration is unknown the value should be null

materials.N.id

A unique identifier for this material. This identifier should be shared between printers. In other words, if two printers both have exactly the same materials loaded in the same way then the values of the materials.N.id properties should be the same for both. The identifier can include information about the material, such as titanium-6AL-4V which indicates a particular alloy of Titanium, Aluminum and Vanadium. It can also be an opaque identifier such as a UUID or trademarked name.

materials.N.quantity

This should be the quantity of materials available in whatever units are supplied in the units property. For that reason it should always be a floating point value. If the quantity is unknown or unknowable the value should be null rather than 0

materials.N.units

The units of measure used to determine the quantity of the material. For example, if the printer measures by unit volume the quantity could be 1004 and the units be milliliters or cubic centimeters. The quantity could be 1.004 and the units could be liters. If the quantity is unknown or unknowable the value for units should be null

online_since

This is the date and time and timezone of when the printer last came online. This is useful for measuring printer uptime and making determinations about scheduled maintenance

sensors

This is an array containing JSON objects which contain details about any sensors on the printer. If there are no sensors the value should be []. Each object in this array should contain the following properties

sensors.N.name

The name of the sensor. This should be unique for the printer. For example, if there are 2 temperature sensors it could make sense to name them temperature1 and temperature2. It may be better to disambiguate the sensor names with a description of the sensor’s purpose or location, like temperature-nozzle and temperature-bed.

sensors.N.taken

The date and time and timezone the sensor reading was taken. This could be set to the current date and time if the sensor reading is taken when the HTTP request is made to get the information. It could also be far in the past if the sensor reading is only taken periodically

sensors.N.units

The units used in the value returned by the value property. For many types of sensors this should be obvious - temperature sensors would supply the temperature scale (degrees celsius or degrees kelvin). For sensors that simply indicate whethor or not a threshold has been crossed this should indicate how to interpret the boolean - is_tripped would mean that a value of true indicates that the sensor has crossed the threshold.

sensors.N.value

This is the value of the sensor. This may be of any valid JSON type depending on the sensor. Temperature sensors may be floating point values in degrees. In that cause the units property should indicate which temperature scale is in use (Celsius, Kelvin). The sensor may be a simple trigger sensor indicating a threshold has been crossed, in which case the value could be the value true. In that case the units would be set to is_tripped.

status

This indicates the printers general status. Manufacturers should be free to include their own statuses that are relevant to their build process, but should consider using some of the following standard statuses

Common printer statuses
Status Description
offline The printer has been disabled, perhaps for maintenance purposes, and is not able to take on new jobs and is not building
error The printer has some kind of failure and cannot continue building or take on new jobs
idle The printer is currently online and able to take on new jobs. It is not currently building anything
preparing The printer has a build and is preparing for the build in some way, but it has not yet started to consume material for the build
building The printer is currently building something
finishing The printer has a build and is finalizing the build in some way. It has fully consumed all materials for the build that will be consumed, but it is not yet ready for the completed build to be removed
occupied The printer has completed its previous build and would be idle, but the finished build needs to be removed first

Examples

Here is an example of several requests to GET /status/

GET /status/
Content-Type: application/json

{
    "current_build"     : null,
    "errors"            : [],
    "materials"         : [{
        "expiration"    : "2017-12-31T00:00:00.000+000",
        "id"            : "PLA-green-3mm",
        "quantity"      : 15.7,
        "units"         : "meters",
    },{
        "expiration"    : "2018-01-31T00:00:00.000+000",
        "id"            : "HIPS-natural-3mm",
        "quantity"      : 11.3,
        "units"         : "meters",
    }],
    "online_since"      : "2017-10-03T04:45:32+000",
    "sensors"           : null,
    "status"            : "idle"
}

The request above shows a printer that is currently not building anything and has no errors. It has two types of materials loaded, nearly 16 meters of green PLA and 11 meters of HIPS in a natural tone. There are no sensors on this printer that report back. This is a relatively simple report that is common for some low-end FDM printers

GET /status/
Content-Type: application/json

{
    "current_build"     : {
        "estimated_end_time": "2017-10-08T05:42:57+000",
        "id"                : "d142ce8d-3973-4d84-9c82-a35a31d1156d",
        "name"              : "iPhone case",
        "percent_completed" : 0.0,
        "start_time"        : "2017-10-08T03:22:43+000",
    },
    "errors"            : [],
    "materials"         : null,
    "online_since"      : "2017-10-03T04:45:32+000",
    "sensors"           : [{
        "name"          : "chamber temperature",
        "taken"         : "2017-10-08T03:22:44.536+000",
        "units"         : "C",
        "value"         : 267.3,
    }],
    "status"            : "preparing",
}

This is a status report from a printer that is building an iPhone case. The printer has not yet started to apply materials to the build which we can tell because the percent_completed property indicate no material has yet been consumed and the status property indicates the printer is preparing which means it has not yet started to consume material for the build. There is a single sensor reporting from this printer which indicates the chamber is at 267.3 degrees celsius. The build is estimated to complete a little over two hours after the build started.

GET /status/
Content-Type: application/json

{
    "current_build"     : {
        "estimated_end_time": "2017-10-08T05:42:57+000",
        "id"                : "d142ce8d-3973-4d84-9c82-a35a31d1156d",
        "name"              : "iPhone case",
        "percent_completed" : 12.7,
        "start_time"        : "2017-10-08T03:22:43+000",
    },
    "errors"            : [{
        "code"          : "out-of-material",
        "detail"        : "The hopper has been emptied, please refill it"
    },{
        "code"          : "build-envelope-below-temp",
        "detail"        : "The build envelope temperature has fallen below 300C"
    }],
    "materials"         : null,
    "online_since"      : "2017-10-03T04:45:32+000",
    "sensors"           : [{
        "name"          : "chamber temperature",
        "taken"         : "2017-10-08T04:03:37.536+000",
        "units"         : "C",
        "value"         : 267.3
    }],
    "status"            : "error"
}

This is the same printer as the previous example but taken a little later when the build has failed. This particular build has failed because it has run out of material. A technician then opened the build envelope door and caused the temperature to fall. The printer is dutifully reporting both error states and indicating through the status property that the build is now in error and cannot proceed without intervention.

GET /history/

Beyond the immediate status of the printer, Echo requires information about the history of what the printer has done. This is very useful in situations where users add Echo to an existing installation and want historical data about how their printers have been used. The GET /history/ endpoint provides that historical information about prints. The endpoint returns an array of JSON objects. Ongoing builds should not be included in this list. Each object in the array should have the following properties

Common printer statuses
Name Type Description
end_time string (ISO 8601 datetime in UTC timezone) The date and time and timezone when the build completed
id string A programmatically generated unique ID for the build. This should ideally be a UUID
materials list A list of the materials used in the build
materials.N.id string A unique identifier for this particular material type
materials.N.quantity float The quantity of the material used in whatever units are supplied
materials.N.units string The unit of measure used to determine quantity
name string The user-supplied name of the build
percent_completed float A number from 0.0 to 100.0 indicating the amount of the total material for the build that was consumed.
start_time string (ISO 8601 datetime in UTC timezone) The date and time and timezone when the current build started
status string The status of the build (completed, cancelled, failed)

end_time

The date, time, and timezone when the build completed, failed or was cancelled. This should be formatted as an ISO 8601 datetime with timezone information

id

The id property for the build should be a globally unique identifier. In other words, the ID should not conflict between two printers of the same model installed in the same location. For this reason they should be automatically generated via software. It is strongly recommended that a standards-compliant UUID be used for this purpose. This value will be used to uniquely identify two builds that happened on the same printer with the same parameters using the same input data that happened at different times.

materials

The materials property contains information, if available, about the materials that were used in the build. In situations where the printer cannot know about its own materials this property should be set to null. This property is a list so that different printers that track or use varying amounts of materials can track as many materials as is appropriate for their process. Each element in the materials array should be a JSON object with the following properties

materials.N.id

A unique identifier for this material. This identifier should be shared between printers. In other words, if two printers both have exactly the same materials loaded in the same way then the values of the materials.N.id properties should be the same for both. The identifier can include information about the material, such as titanium-6AL-4V which indicates a particular alloy of Titanium, Aluminum and Vanadium. It can also be an opaque identifier such as a UUID or trademarked name.

materials.N.quantity

This should be the quantity of materials used for the build in whatever units are supplied in the units property. For that reason it should always be a floating point value. If the quantity is unknown or unknowable the value should be null rather than 0

materials.N.units

The units of measure used to determine the quantity of the material. For example, if the printer measures by unit volume the quantity could be 1004 and the units be milliliters or cubic centimeters. The quantity could be 1.004 and the units could be liters. If the quantity is unknown or unknowable the value for units should be null

name

The name property should be the user-supplied name for the build. This value may be duplicated between builds on the same or different printers. The user should have been given some opportunity to control the name at some point during the preparation of the build. If not, this value can be null

percent_completed

The percent_completed should indicate how much of the total expected material was consumed towards completing the build. This value should be expressed as a value between 0 and 100.0 that is the percentage of the material expected that was used.

start_time

This is the start date and time when the build was initiated. This is not the time when the user requested the build. It may not be the same time as when the first material was deposited for the build. It should be considered the first moment when the machine began the process of performing the build. For processes that require a warming period the time should begin when warming began.

status

This should be the final status of the build. Manufacturers may include additional status values that makes sense for their process, but should consider using one of the following statuses to be consistent with other printer manufacturers.

Completed build status values
Value Description
cancelled The build was cancelled before completing at the users request
completed The build completed successfully and completely
failed The build failed for some reason. This may include unavailability of raw materials, mechanical failure, power outtage, etc.

Examples

Here are some example requests to the /history/ endpoint

GET /history/
Content-Type: application/json

[{
    "end_time"          : "2017-10-04T08:15:33+000",
    "id"                : "c0ffea27-cd13-4743-9e8d-0336d5dd3e2b",
    "materials"         : null,
    "name"              : "iPhone case",
    "percent_completed" : 100.0,
    "start_time"        : "2017-10-04T06:43:01+000",
    "status"            : "completed",
},{
    "end_time"          : "2017-10-04T03:12:03+000",
    "id"                : "757d2dfd-8fff-4f5e-8ff9-42c6bf2df0d1",
    "materials"         : null,
    "name"              : "iPhone case",
    "percent_completed" : 37.1,
    "start_time"        : "2017-10-04T02:47:31+000",
    "status"            : "failed",
}]

This is a very short history report of a printer that attempted to print an iPhone case and failed after using up about 1/3 of the total materials it needed. The user then attempted to print the same job again and was successful after about an hour and a half. The printer does not track material usage or consumption and so has no information available about the materials used in the builds

GET /history/
Content-Type: application/json

[{
    "end_time"          : "2017-10-04T08:15:33+000",
    "id"                : "09dc80d8-223d-4148-a9e5-a25df984a686"
    "materials"         : [{
        "id"            : "234894f1-ef56-4df5-9386-64a6949e7319",
        "quantity"      : "57.8",
        "units"         : "cc",
    }],
    "name"              : "coupon175",
    "percent_completed" : 100.0,
    "start_time"        : "2017-10-04T06:43:01+000",
    "status"            : "completed",
},{
    "end_time"          : "2017-10-04T03:12:03+000",
    "id"                : "926c38d0-cd2e-49f3-94c0-d3abdd19632e"
    "materials"         : [{
        "id"            : "234894f1-ef56-4df5-9386-64a6949e7319",
        "quantity"      : "57.8",
        "units"         : "cc",
    },{
        "id"            : "a6a72068-1676-4537-bc57-c36f8d46a6c0",
        "quantity"      : 44,
        "units"         : "magazines",
    }],
    "name"              : "test14",
    "percent_completed" : 58.352
    "start_time"        : "2017-10-04T02:47:31+000",
    "status"            : "cancelled",
}]

Here is a different historical report. In this the manufacturer does not supply meaningful material IDs, but rather just UUIDs for the materials. We can see that the same material was used for the first and second prints. The first print was cancelled at the users request as it was a little passed halfway complete. We can also see an example of material consumption tracking that uses a non-standard unit, “magazine”. This is for a printer that supplies materials as discrete packages and consumes those packages as part of the build.