We collect many different data points from all connected machines. We call the stream of observations about a specific state or property of a machine a "metric". A single observation is called an event. In other words: each event represents an observation of a value at a certain point in time, the
eventTime. The value can either be a scalar (numeric, string) or expressed as a set of attributes (e.g.,
z). There are different categories of data which we describe in the following chapter.
Each machine has an identifier
machineRef which is an integer that is unique across all machines within MachineMetrics. Every metric that is captured from a machine has a
metricKey that is unique within the context of the entire machine's metric space. In other words: each metric is globally identified by the combination of
metricKey. Metrics are of a specific
type and sometimes an additional
subtype. These Types and Subtypes (see table below for reference) are common across all equipment. However, many metrics can be available on some pieces of equipment while absent on others. Additional context can be used to related metrics to each other using a Component Type and Component Name.
Events are stored in different places depending on their data category. The data category of a metric is determined by its type and subtype. The following table summarizes the categorization.
|Data Category||Type||Subtype||GraphQL Objects|
|QUANTITY||one of||not |
The events of metrics with the types
NonconformCount are not available through the GraphQL API.
Quantities are commanded or sampled physical properties of a machine.
- These metrics usually express physical quantities.
- The number of possible values is generally unbounded (but might be limited by technical properties, eg. number precision).
- The values themselves can be bounded (eg. non-negative).
- The value between observations is generally unknown but sometimes follow the laws of physics and can be interpolated (eg. temperature)
- The usability of the data is dependent on the frequency of the observations (higher frequency for Anomaly detection).
- Path Positions are a special subset of quantities as they have three numeric values:
Quantities can be queried using aggregates:
- Only state changes are relevant. But the data can contain records of unchanged states.
- Observations carry forward (the machine is in the state that was last reported).
- Observations with the same value than the previous one can be dismissed.
- Multiple different states can be reported on the same timestamp. The order of those states is important.
- Metrics have a limited number of distinct values (enumerations).
- State data is categorical (https://en.wikipedia.org/wiki/Categorical_variable)
- State changes might be restricted by rules (a “state machine” in the computer science sense).
- The state change might be triggered by an event having a new state or by an explicit state change. Some states are cleared by a “NORMAL” value on the specific native_code or on an empty native_code (for all).
Heartbeats are a special subset of states and have the following, additional characteristics:
- They are expected to be observed in regular, predefined intervals.
- A missing observation of a heartbeat has a specific meaning (eg.
The machine's execution state state is driven by metrics typed as
Execution. Metrics with this Type can have a value representing one of the following states:
The order above is relevant. Here's why.
Many machines come with multiple execution paths which often translates to multiple metrics independently reporting their state. MachineMetrics produces an artificial metric to reflect the entire machine's status with a key of
MasterExecution. This machine-wide execution status is generated by taking the state across all metrics with an Execution Type that is highest in the above list of states.
For example, if the machine has two metrics (execution, and execution2) representing the status of each of the two paths on the machine with
execution reporting a state of
execution2 reporting a state of
MasterExecution will be reported as
execution is reporting
execution2 is reporting
MasterExecution will be reported as
For most use cases, you can consider this data to represent 3 states:
Machine Alarms (Conditions)
"description": "AUTOMATIC BAR FEEDER NOT READY"
Machine conditions are captured as metrics with a type of
Condition with a variety of Subtypes shown below:
More importantly, each
Condition metric can track any number of distinct Native Codes (or Alarm Codes). These Native Codes are unique to the Make/Model/Family of equipment they are retrieved from. Further, MachineMetrics Adapter Scripts can be used to augment machine data to produce custom "Alarms" for a variety of use cases like historical reporting of Feed Rate Overrides exceeding certain thresholds, to notifying other systems via Webhooks of other condition-based metrics diverging from specified standards.
Any number of distinct Native Codes can be in one of three states on a
In addition to the Native Code,
Condition metrics can (but are not required to) report a severity, message (or label), and qualifier.
- The value is a string.
- The number of possible of values can vary from a single one (manufacturer) to unbounded (G-Code).
- State changes can be restricted by domain level rules (monotonically increasing firmware version).
- Some info metrics can be interepreted as streams of state changes and thus translated into intervals with a defined start and end time.
Counts share the following characteristics:
- The value is usually an integer.
- Values can be absolute or differential (change to previous absolute value).
- Values generally grow monotonically (but can be reset periodically).
The machine's part count is driven by metrics typed as
PartCount. Machines have multiple counters with different purposes which are distinguished by the following Subtypes:
Machines report the value of their part counters which, in the case of all but
REMAINING, increase as parts are made:
MachineMetrics continuously calculates the delta change of each
PartCount metric. By default, all
PartCount metrics with a Subtype of
ALL contribute to the parts MachineMetrics recognizes. If there is a specific
PartCount metric, it can be configured as the explicit counter metric for the machine. Due to the fact that there may be use cases that can take advantage of the other counters, they are all available through our various APIs and export mechanisms; however, the value returned from these systems will be the delta and not the original counter value.
The Meaning of
In cases where MachineMetrics is not able to retrieve data from the equipment, the value for every metric will be reported as
UNAVAILABLE. There are some exceptions to this depending on what mechanisms you are using to retrieve data; however, that is how the data is ingested into our system. One example of an exception to this relates to how the data is exposed via GraphQL. GraphQL is backed by a time-series database where the information is organized in appropriately typed tables based on the value space of the metric. Because of this, metrics representing numerical values (quantities) will have gaps in data where data is
Data is typically sampled from equipment at a rate of 1Hz. Only changes are reported. However, values are refreshed every few minutes to ensure accuracy so repeated values are normal. Because of this behavior, depending on your use case, different interpolation techniques may be necessary.
Carry-forward interpolation is usually sufficient for
State metrics like
Linear or polynomial interpolation might be visually appealing for a timeline when displaying temperature data, but for truly accurate
LOAD data (for example), data sampled at a much higher frequency (1KHz) might be necessary. Contact firstname.lastname@example.org if your use case has these requirements.
Types and Subtypes
A large portion of the capabilities within MachineMetrics are driven by the Types and Subtypes mentioned above, but there are many more that can be used to classify metrics for more unique use cases. This table is a comprehensive list of all Types and Subtypes currently supported. If you have equipment and use case that requires something that is not listed, please contact email@example.com.
|PartCount||TOTAL, ALL, GOOD, BAD, TARGET, REMAINING||Counter|
|Execution||ACTIVE, FEED_HOLD, INTERRUPTED, OPTIONAL_STOP, PROGRAM_STOPPED, PROGRAM_OPTIONAL_STOP, STOPPED, PROGRAM_COMPLETED, UNAVAILABLE, READY|
|SpindleRotating||ON, UNAVAILABLE, OFF|
|Cutting||ON, UNAVAILABLE, OFF|
|EmergencyStop||ARMED, UNAVAILABLE, TRIGGERED|
|ControllerMode||MANUAL, MANUAL_DATA_INPUT, SEMI_AUTOMATIC, EDIT, UNAVAILABLE, AUTOMATIC|
|AccumulatedTime||TOTAL_OPERATING_TIME, TOTAL_RUNNING_TIME, TOTAL_CUTTING_TIME, TOTAL_SPINDLE_RUN_TIME, OPERATING_TIME, RUNNING_TIME, CUTTING_TIME, SPINDLE_RUN_TIME||String|
|Feedrate||ACTUAL, COMMANDED, JOG, PROGRAMMED, RAPID||Scalar|
|RotaryVelocity||ACTUAL, COMMANDED, PROGRAMMED||Scalar|
|Program||PROGRAM, SUBPROGRAM, MAIN_NAME, SUB_NAME||String|
|Pressure||ACTUAL, TARGET, TARGET_LOW, TARGET_HIGH||Scalar|
|EquipmentTimer||LOADED, WORKING, OPERATING, POWERED, DELAY||Scalar|
|EquipmentMode||LOADED, WORKING, OPERATING, POWERED, DELAY||ON, OFF|
|Humidity||ABSOLUTE, RELATIVE, SPECIFIC||Scalar|
|Condition||POSITION, TEMPERATURE, LOAD, ACTUATOR, ANGLE, PRESSURE, LEVEL, COMMUNICATIONS, HARDWARE, SYSTEM, MOTION_PROGRAM, LOGIC_PROGRAM||FAULT, WARNING, UNAVAILABLE, NORMAL|
|Sample||ACCELERATION, ANGULAR_ACCELERATION, ANGULAR_VELOCITY, AMPERAGE, ANGLE, AXIS_FEEDRATE, CLOCK_TIME, CONCENTRATION, CONDUCTIVITY, DISPLACEMENT, ELECTRICAL_ENERGY, FILL_LEVEL, FLOW, FREQUENCY, LENGTH, LINEAR_FORCE, LOAD, MASS, PATH_FEEDRATE, PATH_POSITION, PH, POSITION, POWER_FACTOR, PRESSURE, RESISTANCE, ROTARY_VELOCITY, SOUND_LEVEL, STRAIN, SURFACE_SPEED, TEMPERATURE, TILT, TOOL_LENGTH, TOOL_RADIUS, TORQUE, VOLT_AMPERE, VOLT_AMPERE_REACTIVE, VELOCITY, VISCOSITY, VOLTAGE, WATTAGE, MM_CURRENT_TRANSDUCER, MM_SENSOR_1, MM_SENSOR_2, MM_SENSOR_3, MM_AMPLITUDE||Scalar|
|Override||RotaryVelocity, Feed, Rapid, Jog||Scalar|
|Info||ACTUATOR_STATE, ACTIVE_AXES, AVAILABILITY, AXIS_COUPLING, AXIS_INTERLOCK, AXIS_STATE, BLOCK, CHUCK_INTERLOCK, CHUCK_STATE, CONTROLLER_MODE, COUPLED_AXES, DIRECTION, DOOR_STATE, END_OF_BAR, FIRMWARE_VERSION, FUNCTIONAL_MODE, INTERFACE_STATE, LINE, MATERIAL, MANUFACTURER, MESSAGE, MODEL, OPERATOR_ID, PALLET_ID, PART_ID, PART_NUMBER, PATH_MODE, POWER_STATE, PROGRAM, PROGRAM_EDIT, PROGRAM_EDIT_NAME, PROGRAM_COMMENT, PROGRAM_HEADER, ROTARY_MODE, SERIAL_NUMBER, SPINDLE_INTERLOCK, SPINDLE_MODE, TOOL_ASSET_ID, TOOL_NUMBER, VERSION_NUMBER, WORKHOLDING_ID, MS_BLOCK_DELETE, MS_COOLANT, MS_DRY_RUN, MS_OPERATION_MODE, MS_OPTIONAL_STOP, MS_RESET, MS_SINGLE_BLOCK, MAZAK_TOOL_GROUP, MAZAK_TOOL_SUFFIX, MAZAK_SEQUENCE_NUMBER, MAZAK_UNIT_NUMBER, BRE_WORKPIECE, BRE_NUMBER_ACTIVE_AXES, BRE_LOADED_PROGRAM_NAME, BRE_INT_COOLANT, BRE_EXT_COOLANT, MM_SYSTEM_TYPE, MM_ADAPTER_INFO, MM_DEVICE_ADDRESS, MM_MACHINE_NAME, MM_MACHINE_STATUS, MM_MESSAGE_EVENT, MM_DOWNTIME_CODE, MM_CYCLE_RATE, MM_WORK_COUNTER_CODES, MM_SCAN_INTERVAL, MM_INTERLOCK, MM_TOOL_CUTS, MM_OPERATION_COUNT, BUL_CHUCK_SELECT, BUL_CUT_AREA, BUL_CALIBRATION_INTERLOCK, BUL_OPERATOR_INTERLOCK, BUL_REWORK_COUNT, BUL_OPERATION_MODE, BUL_CUTTING_MODE, BUL_SUPERVISOR_OVERRIDE, BUL_CYCLE_START,||String|