Cálculo de KPI con órdenes de trabajo en lugar de turnos
Como personalización, es posible calcular los KPI utilizando órdenes de trabajo en lugar de turnos como periodo de tiempo. De esta forma, se calculan los KPI a lo largo de la duración de una orden de trabajo, desde el inicio hasta la finalización, cuando ese periodo de tiempo puede abarcar varios turnos.
* 
Los KPI se pueden calcular usando los turnos o las órdenes de trabajo del periodo de tiempo. Esta personalización cambia el cálculo de todos los KPI para que utilicen las órdenes de trabajo.
Una vez implantada esta personalización, cada vez que se calculan los KPI, el sistema recupera todas las órdenes de trabajo en ejecución. Las órdenes de trabajo en ejecución son aquellas para las que se cumplen las dos afirmaciones siguientes:
La hora actual es posterior a la hora de inicio real de la orden de trabajo.
La hora de finalización real de la orden de trabajo no está definida.
Para cada orden de trabajo recuperada, se encuentran todos los activos que hacen referencia al UID de la orden de trabajo. Los valores de KPI actuales para esos activos se calculan en función del inicio real de la orden de trabajo y la hora actual.
A fin de personalizar el cálculo de KPI para que utilicen órdenes de trabajo, complete los pasos siguientes:
Personalización del administrador de KPI
1. Cree una cosa de administrador de KPI que extienda PTC.SCA.SCO.KPIManagerThingTemplate.
a. Pulse en Nuevo y seleccione Cosa.
b. En Nombre, indique un nombre para la cosa.
c. En Plantilla de cosa base, seleccione PTC.SCA.SCO.KPIManagerThingTemplate o una plantilla de cosa que extienda PTC.SCA.SCO.KPIManagerThingTemplate.
d. Pulse en Guardar para guardar la nueva plantilla de cosa.
2. Edite el valor de KPIManager definido para el sistema.
a. Navegue a la cosa de configuración de puntos de inicio (PTC.Factory.C_LaunchPointConfigurationThing_[versión]).
b. En Configuración, en la tabla ManagerConfigurationSettings, pulse en para editar KPIManager. Cambie Value a la cosa de administrador de KPI creada en el paso 1; a continuación, pulse en Definir.
c. Pulse en Guardar para guardar los cambios en la cosa de configuración del punto de inicio.
3. En la nueva cosa de administrador de KPI, cree un servicio para recuperar las órdenes de trabajo que están en ejecución.
a. En Servicios, pulse en Añadir.
b. En Nombre, escriba GetRunningJobOrders.
c. En Salida, seleccione INFOTABLE en el menú desplegable. En Definición de datos, busque PTC.SCA.SCO.JobOrder y selecciónela.
d. Introduzca el código siguiente en el editor de servicios:

var filters = {
"filters": {
"filters": [
{
"dataShapeName": "PTC.SCA.SCO.JobOrder",
"fieldName": "ActualStartTime",
"type": "LE",
"value": new Date()
},
{
"dataShapeName": "PTC.SCA.SCO.JobOrder",
"fieldName": "ActualEndTime",
"type": "MISSINGVALUE"
}

],
"type": "AND"
},
"sorts": [
{
"fieldName": "ActualStartTime",
"isAscending": true
}
]
}
// result: THINGNAME
var productionOrder = Things["PTC.Factory.LaunchPointConfigurationThing"].GetProductionOrderManagerThingName();
// result: INFOTABLE dataShape: "PTC.SCA.SCO.JobOrder"
var result = Things[productionOrder].GetJobOrders({
filter: filters /* JSON */,
offset: -1 /* INTEGER */,
limit: 99999999 /* INTEGER */
});
e. Pulse en Guardar y continuar.
4. En la nueva cosa de administrador de KPI, cree un servicio para recuperar todas las cosas de equipo para las cuales se calculan los KPI en relación con esta orden de trabajo.
a. En Servicios, pulse en Añadir.
b. En Nombre, escriba GetKPIElementsFromJobOrder.
c. En Entradas, pulse en Añadir. En Nombre, indique JobOrderUID.
d. En Salida, seleccione INFOTABLE en el menú desplegable.
e. Introduzca el código siguiente en el editor de servicios:
//Calculate all elements value
//Retrieve all KPIElement things
var elementThingShape = "PTC.SCA.SCO.KPIElementThingShape";
var maxItems = 300;
var filter = {
"filters" : {
"type" : "EQ",
"fieldName" : "JobOrderUID",
"value" : JobOrderUID
}
};

var tmpResult = Resources["SearchFunctions"].SearchThings({
searchExpression: undefined /* STRING */,
modelTags: undefined /* TAGS */,
networks: undefined /* JSON */,
types: {"items":["Thing"]} /* JSON */,
thingTemplates: undefined /* JSON */,
thingShapes: {"items":["PTC.SCA.SCO.KPIElementThingShape"]} /* JSON */,
aspects: undefined /* JSON */,
excludedAspects: undefined /* JSON */,
identifierSearchExpression: undefined /* STRING */,
query: filter /* QUERY */,
maxItems: maxItems /* NUMBER */,
maxSearchItems: maxItems /* NUMBER */
});
var result = tmpResult.getRow(0).thingResults;
f. Pulse en Guardar y continuar.
5. En la nueva cosa de administrador de KPI, busque y modifique el servicio GetKPIElementsFromTimeInfo.
6. Sustituya el contenido del editor de servicios por el código siguiente:
var jobOrderUID = TimeInfo.getRow(0).UID+"";
var result = me.GetKPIElementsFromJobOrder({
JobOrderUID: jobOrderUID /* STRING */
});
7. Pulse en Terminado y, a continuación, en Guardar.
Personalización del programador de cálculo de KPI
Complete el procedimiento siguiente para personalizar el programador de cálculo de KPI:
1. Vaya a PTC.SCA.SCO.KPIScheduler.
2. En Servicios, sustituya el servicio GetTimeInfos.
3. Sustituya el contenido del editor de servicios por el código siguiente:
var params = {
infoTableName : "InfoTable",
dataShapeName : "PTC.SCA.SCO.TimeInfo"
};
// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(PTC.SCA.SCO.TimeInfo)
var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params);

//Retrieve All JobOrders
var jobOrders =Things[Things["PTC.Factory.LaunchPointConfigurationThing"].GetKPIManagerThingName()].GetRunningJobOrders();
var tableLength = jobOrders.rows.length;
for (var x=0; x < tableLength; x++) {
var row = jobOrders.rows[x];
var uid = row.UID;
//Your code here
// PTC.SCA.SCO.ShiftInfo entry object
var newEntry = new Object();
newEntry.UID = uid; // LONG
newEntry.StartTimeDate = row.ActualStartTime; // DATETIME
newEntry.GeneratedID = 'JobOrder-'+uid; // STRING [Primary Key]
//newEntry.EndTimeDate = undefined; // DATETIME
newEntry.SiteUID = undefined; // LONG
result.AddRow(newEntry);
}
4. Pulse en Terminado y, a continuación, en Guardar.
Asociación de órdenes de trabajo a equipos
Asocie una orden de trabajo a un equipo individual estableciendo la propiedad JobOrderUID de la cosa de equipo en el UID de la orden de trabajo. Cuando se calculan los KPI para el equipo, la referencia de la orden de trabajo se guarda como parte de los datos históricos del KPI.
Procedimiento para asociar un equipo, como un activo o una línea, con una orden de trabajo:
1. En ThingWorx Composer, vaya a la cosa del equipo. Por defecto, el nombre de la cosa en ThingWorx Composer es el nombre de equipo que se muestra en ThingWorx Apps, precedido por el tipo de equipo. Por ejemplo, para un activo llamado 1-2_GantryRobot, el nombre de cosa es Asset_1-2_GantryRobot.
2. En Propiedades y alertas, defina el valor de la propiedad JobOrderUID en el UID de la orden de trabajo correspondiente.
* 
Cuando se crea una orden de trabajo, la salida del servicio CreateJobOrders devuelve el UID de dicha orden. Como alternativa, se puede utilizar el servicio GetJobOrders para recuperar las órdenes de trabajo de la base de datos, incluidos sus UID. Ambos servicios se encuentran en el administrador de órdenes de producción por defecto (PTC.SCA.SCO.DefaultProductionOrderManager).
3. Pulse en Guardar para guardar las actualizaciones de la cosa.
Para obtener más información sobre las órdenes de trabajo, consulte Esquema de orden de trabajo.
Inicio de una orden de trabajo
Inicie una orden de trabajo configurando la propiedad ActualStartTime de dicha orden.
Procedimiento para establecer la hora de inicio de una orden de trabajo:
1. En ThingWorx Composer, vaya al administrador de órdenes de producción por defecto (PTC.SCA.SCO.DefaultProductionOrderManager).
2. En Servicios, ejecute el servicio UpdateJobOrders.
3. En la tabla de parámetros de entrada JobOrders, pulse en Añadir y proporcione el UID de la orden de trabajo que se va a actualizar. Introduzca el nuevo valor del campo ActualStartTime. Deje los demás campos en blanco. Pulse en Añadir para añadir la información actualizada a la tabla de parámetros de entrada.
Es posible actualizar varias órdenes de trabajo añadiéndolas individualmente a la tabla de parámetros de entrada JobOrders.
4. Pulse en Ejecutar.
Cierre de la orden de trabajo y activación del cálculo final de KPI
Cierre una orden de trabajo configurando la propiedad ActualEndTime de dicha orden. Cuando se cierra una orden de trabajo, se debe activar un cálculo final de KPI. Después de realizar el cálculo final de KPI, se puede eliminar la asociación entre la orden de trabajo y el equipo.
El siguiente procedimiento crea un servicio que cierra la orden de trabajo estableciendo la hora de finalización, activa el cálculo final de KPI y limpia la asociación entre la orden de trabajo y el equipo.
1. En el nuevo administrador de KPI, en Servicios, pulse en Añadir.
2. En Nombre, escriba CompleteJobOrder.
3. Introduzca el código siguiente en el editor de servicios:
// result: INFOTABLE dataShape: "PTC.SCA.SCO.JobOrder"
var jobOrderManager = Things[Things["PTC.Factory.LaunchPointConfigurationThing"].GetProductionOrderManagerThingName()];
// result: INFOTABLE dataShape: "PTC.SCA.SCO.JobOrder"
var jobOrder = Things["PTC.SCA.SCO.DefaultProductionOrderManager"].GetJobOrder({
UID: jobOrderUID /* STRING */
});
//Update end Date
jobOrder.getRow(0).ActualEndTime = new Date();
var updatedJobOrder = jobOrderManager.UpdateJobOrders({
JobOrders: jobOrder /* INFOTABLE */
});
// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(PTC.SCA.SCO.TimeInfo)
var timeInfo = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape( {infoTableName : "InfoTable", dataShapeName : "PTC.SCA.SCO.TimeInfo"
});

var jobOrder = updatedJobOrder.rows[0];
var uid = jobOrder.UID;
// PTC.SCA.SCO.ShiftInfo entry object
var newEntry = new Object();
newEntry.UID = uid; // LONG
newEntry.StartTimeDate = jobOrder.ActualStartTime; // DATETIME
newEntry.EndTimeDate = jobOrder.ActualEndTime; // DATETIME
newEntry.GeneratedID = 'JobOrder-'+uid; // STRING [Primary Key]
newEntry.SiteUID = undefined; // LONG
timeInfo.AddRow(newEntry);

Things["PTC.SCA.SCO.KPIScheduler"].CalculateKPIsForTimeInfo({
TimeInfo: timeInfo /* INFOTABLE */
});

// result: INFOTABLE dataShape: ""
var result = Things[Things["PTC.Factory.LaunchPointConfigurationThing"].GetKPIManagerThingName()].GetKPIElementsFromJobOrder({
JobOrderUID: jobOrderUID /* STRING */
});
//Remove job order reference from the thing
var tableLength = result.rows.length;
for (var x=0; x < tableLength; x++) {
var row = result.rows[x];
//Your code here
Things[row.name].JobOrderUID = undefined;
}
4. Pulse en Terminado y, a continuación, en Guardar.