MachineMetrics

The MachineMetrics Developer Hub

Welcome to the MachineMetrics developer hub. You'll find comprehensive guides and documentation to help you start working with MachineMetrics as quickly as possible. Let's jump right in!

Total In-Cycle Milliseconds by Machine

The Production API is very flexible in that it allows you to group data in various ways and extract different data points such as in-cycle time, parts produced, quality, etc. This example details how to use the Production API to get the total amount of time that a machine was in-cycle since it was first connected to MachineMetrics.

Getting Started

For starters, you're going to need a token to authorize your requests to our API. The easiest approach is to use an API key, but OAuth is also available if it's required for your implementation. To get an API key, go to app.machinemetrics.com/account/api-keys. The “reporting” scope is required for this API endpoint, so be sure to select that scope when creating your key.

There are four major parts to a request: the URL, the method, the headers, and the body.

The URL

The URL for this particular API endpoint is https://api.machinemetrics.com/reports/production

The Method

Every web request has a method associated with it in addition to its URL. When you go to a website like https://www.google.com, the first request is a GET request — the HTTP verb that is being used (or its method) is GET. For the Production API endpoint, a POST method is used so we can take advantage of the body portion of the request which we'll get to momentarily.

The Header

Every web request also contains headers. These are used to provide authentication information, tell the server what type of format the response should be in, or other meta data that are needed to process the request.

All of our endpoints require 2 headers: Authorization and Content-Type. The value of the Authorization header is Bearer API_KEY.

The Body

The body is where you supply your query. For detailed information about all query options, go to https://developers.machinemetrics.com/v0.9/reference

For this case, the body should look like the following:

{
    "start": "2014-01-01T00:00:00Z",
    "end": "2019-05-05T00:00:00Z",
    "groupBy": [{ "group": "machine" }],
    "data": [{ "metric": "timeInCycle" }]
}

Every query requires a time range. It doesn't really make sense for this particular use case, but if we choose a start date far enough into the past, we can get a picture of the overall in-cycle time across the entire period of time that a machine was monitored with our product. These times must be in ISO 8601 format. If you do not include a timezone offset, UTC will be assumed.

start - some date far enough in the past to capture the entire range of time that the equipment was monitored by MachineMetrics.
end - set this to tomorrow so we get all of the data in our system and don't crop any off the end.
groupBy - this is how the data will be segmented. For the use case of getting in-cycle data for every machine, we must group by the machine entity.
data - this is an array of all the different data items you're interested in. In this case, we're only interested in timeInCycle. This represents the number of milliseconds that a machine was in-cycle (this can be thought of as actively running a program).

Example

Below is an example of how to perform this query using a tool called curl. There is an additional example of an asynchronous C# static method (this example uses Newtonsoft's Json.NET package to generate the payload, which can be found here ). (Note that you must replace API_KEY with the one you got from the Getting Started section above. Further to ensure safety and security of your API Keys, avoid storing them in your codebase; instead consider setting them as environment variables and reading those environment variables from your program)

curl -X POST \
  https://api.machinemetrics.com/reports/production \
  -H 'Authorization: Bearer API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "start": "2014-01-01T00:00:00Z",
    "end": "2019-05-05T00:00:00Z",
    "groupBy": [{ "group": "machine" }],
    "data": [{ "metric": "timeInCycle" }]
}
using System;
using System.Text;
using System.Net.Http;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class MMAPI {
  public static async Task requestMachineMetricsUtilizationReport() {
      var payload = new JObject();
      payload["start"] = "2014-01-01T00:00:00Z";
      payload["end"] = "2019-05-05T00:00:00Z";
      JObject groupBy = new JObject();
      groupBy["group"] = "machine";
      payload["groupBy"] = new JArray(groupBy);
      JObject data = new JObject();
      data["metric"] = "timeInCycle";
      payload["data"] = new JArray(data);
      
      var payloadString = JsonConvert.SerializeObject(payload);
      var response = await MMAPI.requestMMAPI("/reports/production", "Bearer API_KEY", payloadString, HttpMethod.Post);
      Console.WriteLine(response);
  }
	
  //This requestMMAPI method can be passed any of our valid endpoints (assuming proper credentials with your API Key). In combination with a JSON library, it's possible to easily build out a custom api access interface
  static async Task<string> requestMMAPI(string path, string apiKey, string payload, HttpMethod httpMethod) {
      var baseUrl = "https://api.machinemetrics.com";
      var client = new HttpClient();
      var request = new HttpRequestMessage(httpMethod, $"{baseUrl}{path}");
      request.Headers.Add("Authorization", apiKey);
      request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
      var response = await client.SendAsync(request);
      var resultContent = await response.Content.ReadAsStringAsync();
      return resultContent;
  }

// This static method (requestMachineMetricsUtilizationReport) can then be invoked asynchronously elsewhere like this:
using static MMAPI;
class Program{
  static void Main(){
    MMAPI.requestMachineMetricsUtilizationReport().Wait();
  }
}

Below is what you'll get back from the above query. This is a long block. Lots to unpack, so before scrolling down, we'll walk through each section:

range This is basically an echo back of the time range that was provided in the query. However, due to how the data is stored, we might not have the exact time periods requested. This range will indicate that data for a wider range of time was captured than was originally requested.
csv If the request included csv: true, this section will provide you with a URL to retrieve the data in CSV format along with the timestamp of when that link expires.
aggregate This section includes every metric requested rolled up across the entire data set.
entities This is a list of every entity type along with information that can be used for display purposes. This reduces the amount of redundancy in the data set.
items This is a nested set of arrays based on the grouping provided in the requested query. In this case, we only grouped by "machine" so there is only one layer to the items block. Each item has an entity and an aggregate. The entity has a type and ID which can be used to look up the name in the entities block. The aggregate is a hashtable of all the data metrics requested with their respective values which are rolled up for the given grouping.
{
    "range": {
        "start": "2014-01-01T00:00:00.000Z",
        "end": "2019-05-05T00:00:00.000Z"
    },
    "csv": {
        "url": null,
        "expires": null
    },
    "aggregate": {
        "timeInCycle": 3404990284
    },
    "entities": {
        "machine": {
            "c37b9f9f-cb70-47b0-ac89-1cff25024cb8": {
                "id": "c37b9f9f-cb70-47b0-ac89-1cff25024cb8",
                "name": "CNC 1"
            },
            "dd942a48-67be-4bc5-9d34-281c9554183a": {
                "id": "dd942a48-67be-4bc5-9d34-281c9554183a",
                "name": "CNC 2"
            },
            "f0758dea-7277-4561-b337-3e8489ffb6ed": {
                "id": "f0758dea-7277-4561-b337-3e8489ffb6ed",
                "name": "CNC 3"
            },
            "cbca14c6-ed91-4bac-99a2-ff339e66c818": {
                "id": "cbca14c6-ed91-4bac-99a2-ff339e66c818",
                "name": "CNC 4"
            }
        }
    },
    "items": [
        {
            "entity": {
                "type": "machine",
                "id": "c37b9f9f-cb70-47b0-ac89-1cff25024cb8"
            },
            "aggregate": {
                "timeInCycle": 2807065907
            }
        },
        {
            "entity": {
                "type": "machine",
                "id": "dd942a48-67be-4bc5-9d34-281c9554183a"
            },
            "aggregate": {
                "timeInCycle": 597856520
            }
        },
        {
            "entity": {
                "type": "machine",
                "id": "cbca14c6-ed91-4bac-99a2-ff339e66c818"
            },
            "aggregate": {
                "timeInCycle": 67857
            }
        },
        {
            "entity": {
                "type": "machine",
                "id": "96ace055-bb5a-4345-afdb-705adb59ee96"
            },
            "aggregate": {
                "timeInCycle": 0
            }
        }
    ]
}

Total In-Cycle Milliseconds by Machine


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.