Documentación de la API de transmisiones de imágenes y vídeos
Esta página trata sobre la creación de software para enviar imágenes y videos desde una fábrica a Instrumental. Se supone que ha leído¿Cómo importo y uso imágenes y videos? y ha trabajado con un arquitecto de soluciones instrumentales para decidir que esta es la mejor opción de implementación. Si ese es el caso, significa que tienes una forma de obtener las imágenes o los vídeos que deseas enviar, así como un lugar donde puedes ejecutar el script de integración que necesitarás escribir.
Después de comprar transmisiones de imágenes o transmisiones de video, Instrumental configurará un proyecto de prueba en la aplicación web de Instrumental para que pueda desarrollar una integración sin enviar datos de prueba a su proyecto "real".
Tabla de contenidos
Claves API
Para enviar datos, necesitará una clave API con permisos de "escritura". Puede leer sobre las claves API y cómo obtenerlas en la página de claves API.
API de transmisiones de imágenes y vídeos
Dominio/punto final
Enviar datos a https://api.instrumental.ai/api/v0/externalData/ingestImage
con el POST
método HTTP.
Trabaja con tus equipos de redes para desbloquear TCP en el puerto 443 (acceso HTTPS) para este dominio en cualquier red que ejecute tu script de integración. El dominio no tiene una dirección IP fija ni un rango de IP, por lo que el dominio en sí debe estar permitido. Si es necesario, Instrumental puede analizar la configuración de un proxy con una IP fija.
Las solicitudesdebentener los siguientes encabezados:
clave-api-instrumental: YOUR_API_KEY
tipo de contenido: aplicación/json
Por supuesto, reemplace YOUR_API_KEY
con su clave completa real (debe contener INST:V1
; no use solo el identificador que se muestra en el modal de clave API).
Límites predeterminados
Las imágenes y vídeos cargados pueden tener hasta 50 megabytes. Las solicitudes más grandes se rechazarán con un error 413 Demasiado grande . El componente JSON de las solicitudes puede tener hasta 4 MB.
Los clientes tienen un límite de velocidad de 50 solicitudes de ingesta rellenadas a una velocidad de 5 por segundo, compartidas entre todos los puntos finales de la API de ingesta. Esto permite cierta capacidad de ráfaga si necesita enviar más solicitudes durante un período breve. En algunas circunstancias, se pueden aplicar límites de tarifaspor sitio de fábrica. Si se excede el límite de tasa, las solicitudes se rechazarán con un error 429 Demasiadas solicitudes hasta que el depósito de límite de tasa se rellene lo suficiente para que lleguen nuevas solicitudes.
Además, al cargar imágenes y videos, puede especificar metadatos como el nombre de la estación que tomó la imagen o el video. Hay límites sobre la cantidad de valores diferentes que se pueden proporcionar en estos campos por proyecto:
- 50 compilaciones
- 50 líneas
- 1000 configuraciones
- 500 nombres de estaciones
- 1000 ID de dispositivos de estación
- 1000 tipos de imágenes/vídeos
Cada unidad (número de serie único) no puede tener más de 500 inspecciones de imágenes/videos, 500 imágenes/videos en total y 349 subconjuntos. En los casos en que los subconjuntos se fusionen en un conjunto final, estos límites se aplican a la unidad fusionada, no a cada componente individualmente. Si una unidad fusionada excede estos límites, solo se mostrará un subconjunto de datos, junto con una advertencia de que este es el caso.
Si espera exceder cualquiera de los límites descritos anteriormente, hable con su administrador de cuentas o arquitecto de soluciones.
Solicitar
El punto final acepta contenido en formato multipart/form-data
con dos partes: un archivo de imagen o vídeo con una clave file
y un objeto JSON con una clave data
.
Ejemplos
- Haga clic para ver un ejemplo usando cURL en la línea de comando:
- Haga clic para ver un ejemplo usandoPython:
Validación
Cuando se cargan imágenes y vídeos, se validan de forma asincrónica y se analizan en busca de virus antes de que estén disponibles en la aplicación web de Instrumental. Para pasar la validación, las imágenes deben estar en formato JPEG y los videos deben estar en formato MP4 o WEBM. Las imágenes y los vídeos deben tener 32 MP o menos (aproximadamente 6528 x 4896 px con una relación de aspecto de 4:3, por ejemplo). Si el nombre del archivo no termina en .jpg, .jpeg, .mp4 o .webm, se rechazará de forma sincrónica.
El vídeo debe utilizar un códec que realmente pueda reproducirse en navegadores web (por ejemplo, H264, AV1, VP9, VP8, no mp4v). Puedes verificar el códec de tu video instalando
ffmpeg (en macOS con homebrew, puedes instalar con brew install ffmpeg
) y ejecutando este comando, sustituyendo la ruta a tu video:
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 /PATH/TO/VIDEO.mp4
Deberías recibir una respuesta como h264
. Si en su lugar obtienes mpeg4
, convierte tu vídeo al códec h264 con este comando, sustituyendo las rutas:
ffmpeg -i /PATH/TO/INPUT_VIDEO.mp4 -c:v libx264 /PATH/TO/OUTPUT_VIDEO.mp4
Parámetros
Esta es la forma de la parte JSON de la solicitud:
{
"serialNumber": "Unit SN",
"stationName": "Nombre de la estación",
"imageType": "Nombre de lo que muestra la imagen/video",
"imageTimestamp": {
"ianaTimeZone": "America/Los_Angeles",
"iso8601Time": "AAAA-MM-DDTHH:mm:ss.SSSZ"
},
"tags": [
"Etiqueta opcional 1",
"Etiqueta opcional 2",
],
"configName": "Nombre de configuración opcional",
"imageConfigs": {
"configs": {
"CustomAttribute": "CustomValue"
}
},
"fixtureName": "ID de dispositivo de estación opcional",
"fileName": "Nombre de archivo opcional",
"lineName" : "Nombre de línea opcional",
"buildName" : "Nombre de compilación opcional",
"parentAssembly": {
"unitSerial": "SN principal",
"relationshipName": "Pantalla"
},
"subassemblies": [
{
"unitSerial": "SN secundario",
"relationshipName": "Cubierta de vidrio"
},
...
]
}
Más detalladamente:
Parámetros requeridos
número de serie: cadena
El número de serie asociado con la unidad inspeccionada. La imagen/video cargado se mostrará con este SN en la aplicación web. Si tiene imágenes/videos que no están asociados con un número de serie específico (por ejemplo, si tiene un código de lote pero no identificaciones separadas para unidades específicas en ese lote), consulte con su arquitecto de soluciones instrumentales sobre qué colocar en este campo. No debe ser una cadena vacía.
nombre de la estación: cadena
Nombre de la estación donde se capturó la imagen/vídeo. No debe ser una cadena vacía.
tipo de imagen: cadena
Describe lo que hay en la imagen/vídeo, p. “PCB Post-Glue” o “Superior terminada en buen estado”. no debe ser único por imagen/vídeo; más bien, las imágenes/vídeos que tienen la misma vista del producto en el mismo punto de la línea de montaje deben tener el mismo imageType
. Debido a esto, cada imageType
solo debe usarse en una estación. Hable con su representante de Instrumental Customer Success si planea mover un imageType
a una estación diferente o si planea cambiar lo que está en la vista sin cambiar el nombre del imageType
o usar diferentesimageConfigs
(que se analizan a continuación). Cuando crea un monitor para detectar defectos en las imágenes, el monitor se asociará con un imageType
y analizará todas las fotos nuevas con ese imageType
. No debe ser una cadena vacía.
imageTimestamp.iso8601Time: cadena de fecha y hora ISO 8601
La hora a la que se tomó esta imagen/vídeo, como una cadena de tiempoISO 8601 es decir:“AAAA-MM-DDTHH:mm:ss.SSSZ”. La cadena no tiene que estar en UTC, pero tenga en cuenta que cualquier compensación aquí se usará solo para determinar el momento en el tiempo, no para ninguna matemática adicional de zona horaria (por ejemplo, calcular la hora del “reloj en la pared”). En su lugar, se utilizará la cadena de zona proporcionada en el campo "ianaTimeZone" de este registro.
imageTimestamp.ianaTimeZone: DateTimeZone
La zona horaria en la que se tomó esta imagen/vídeo, como un nombre de zona horaria que se encuentra en la base de datos IANA tz, por ejemplo: “América/Los_Ángeles”, “Asia/Shanghái”.
Parámetros opcionales
etiquetas: matriz[cadena]
Metadatos cortos asociados directamente con la imagen/vídeo que deben estar presentes al visualizar la imagen/vídeo en la aplicación web. Se pueden proporcionar hasta 100 etiquetas por solicitud. Las etiquetas se utilizan mejor cuando no son únicas pero tampoco están en todas las imágenes/vídeos, por ejemplo, como una forma de indicar que un ingeniero sacó la unidad representada de la línea para desmontarla. Sin embargo, en lugar de usar etiquetas, a menudo es preferible usar la API de Data Streams para cargar datos basados en texto. Data Streams admite datos estructurados, por lo que se pueden visualizar de formas más interesantes.
configName: cadena
La variante/SKU del producto que se muestra en la imagen/vídeo.
imageConfigs: map[string, string]
Atributos personalizados que Monitor y Discover pueden filtrar para evitar detectar variaciones esperadas como anomalías. Actualmente ignorado para vídeos.
Nombre del dispositivo: cadena
El ID del dispositivo/cámara utilizado para capturar la imagen/vídeo. Útil cuando hay varias cámaras en la misma estación.
nombre de archivo: cadena
Mayormente ignorado. Si carga una imagen/vídeo a través de la API Image Streams y luego lo descarga más tarde a través de la aplicación web, el nombre del archivo descargado comenzará con un prefijo aleatorio y terminará con una versión desinfectada de este nombre de archivo especificado, si se proporciona; si no se proporciona, se podría extraer un nombre de archivo de la parte del archivo de la solicitud de carga y usarlo como sufijo.
lineName: cadena
El nombre de la línea de montaje en la que se capturó la imagen/vídeo. Si no se proporciona uno, el nombre de la línea se registrará como "Image Stream Line".
buildName: string
La compilación que estaba activa cuando se tomó esta imagen/vídeo. Si no se proporciona uno, se utilizará la compilación actual del proyecto.
parentAssembly: APIExternalDataAssemblyRelationship
subassemblys: array[APIExternalDataAssemblyRelationship]
Nota: estos campos solo están disponibles para proyectos creados después del 18 de abril de 2022. Comuníquese con Instrumental si desea usarlos para proyectos creados antes de esa fecha.
Estos campos definen cómo se combinan los componentes con sus propios números de serie para producir el ensamblaje final. Por ejemplo, un dispositivo podría tener una estructura como esta:
Ensamblaje final: ENC2124
├─ Subconjunto de PCB: PCB4149
├─ Subconjunto de pantalla: DIS8801
| ├─ Subconjunto de cubreobjetos: GLS1035
├─ Subconjunto de batería: BAT7257
Es probable que las relaciones no se conozcan en cada paso de la inspección; por ejemplo, cuando se inspecciona la batería, es posible que no se sepa en qué gabinete irá. Está bien; las relaciones solo deben cargarse una vez y solo en una dirección (aunque volver a hacerlo no hará daño).
Los ensamblajes pueden tener varios subensamblajes pero solo un padre "activo". Si un ensamblado ya tiene un padre y usted carga una relación que le daría un padre diferente, la solicitud más reciente se convierte en la "activa". Tenga en cuenta que las relaciones de ensamblaje pueden no tener ciclos. Es decir, se devolverá un error al intentar cargar una relación que provocaría que un ensamblado tuviera otro ensamblado entre sus ancestros y descendientes, incluso si uno de los eslabones de esa cadena no está "activo".
Si carga un subensamblaje sin un padre, inicialmente se representará como su propia unidad en la aplicación Instrumental. Cuando se establece una relación con uno de los padres, se fusionará con la unidad de padres. Esta combinación permite revisar y correlacionar los datos de todos los componentes de un ensamblaje final. Si el ensamblaje principal activo de un componente cambia, se separará de su padre anterior y se fusionará con el nuevo.
Si está realizando una carga masiva, sus datos estarán disponibles en la aplicación más rápido si carga las relaciones de las unidades antes o en la misma solicitud en la que carga las primeras inspecciones de esas unidades porque Instrumental puede entonces fusionar los ensamblajes inmediatamente en lugar de crearlos por separado y fusionarlos más tarde.
Relación APIExternalDataAssembly
unitSerial: cadena
El número de serie de la unidad en el otro lado de la relación descrita.
relationshipName: cadena
El nombre del subensamblaje en relación con el ensamblaje principal, p. “Pantalla izquierda”.
Respuesta
Si la solicitud se realiza correctamente, la respuesta tendrá un código de estado HTTP de 200 y el cuerpo de la respuesta será un objeto JSON con solo una clave fileId
, como { "fileId": "e0Blm7EjlLQ2" }
. Después de que regrese la solicitud, habrá un retraso de hasta 60 segundos antes de que el archivo aparezca en la aplicación web Instrumental. Para verificar el estado de sus cargas, consulte la sección Comprobación del estado del archivo a continuación.
Una vez que el archivo esté disponible en la aplicación web, puede visitar https://app.instrumental.ai/files/{fileId}
para verlo, reemplazando {fileId}
con la cadena de la respuesta de API. Lo más probable es que quieras encontrarlo explorando/filtrando unidades en la pestaña Explorar.
Las solicitudes fallidas recibirán uno de los siguientes códigos de estado HTTP:
- 400 – Error al analizar o validar la solicitud
- 401: clave API no válida en el encabezado
- 413: la solicitud es demasiado grande; consulte la sección Límites predeterminados
- 429 – Límites de tarifas excedidos; consulte la sección Límites predeterminados
- 500 – Error del servidor
Si una solicitud falla con uno de estos códigos de estado, no se guardará ninguna de las partes de la solicitud.
En el caso de un error 400, el cuerpo de la respuesta normalmente tendrá la estructura { "code": "CODE", "msg": "Explanation" }
. El código será una de las siguientes cadenas:
- INVALID_DATA: El campo
serialNumber
,stationName
oimageType
está vacío o el nombre del archivo no termina en una de las extensiones de archivo permitidas. - REQUEST_DATA_NOT_FOUND: No no la sección
data
estaba presente en la solicitud. - IMAGE_FILE_NOT_FOUND:No había ninguna sección
archivo
en la solicitud. - FILE_TOO_BIG: La parte del archivo de la solicitud superó el tamaño máximo; consulte la sección Límites predeterminados.
- LIMIT_EXCEEDED: Esta solicitud habría creado demasiadas entidades; consulte la sección Límites predeterminados.
- INVALID_ASSEMBLY_RELATIONSHIPS: Al menos una de las relaciones de subensamblaje/ensamblaje principal especificadas en la solicitud causó un problema como exceder el número máximo de subensamblajes permitidos.
Sin embargo, si la solicitud no tiene el formato JSON válido o si la estructura JSON no coincide con el formato descrito anteriormente, el cuerpo de la respuesta tendrá un formato diferente que describe lo que está mal. Por ejemplo, es posible que vea un mensaje como este:
{"error":"No se pudo analizar el cuerpo de la solicitud con el formato JSON esperado.","reason":"ERROR :: /fieldName :: explicación de la forma que se supone que debe tener el campo"}
Errores de revisión
Lassolicitudes de API que se autentican correctamente (es decir, que tienen un encabezado instrumental-api-key
válido y no tienen una tasa limitada) pero que fallan en otra validación (por ejemplo, el cuerpo de la solicitud no es válido) serán accesibles temporalmente para su depuración a través del modo de clave API. Puede leer más sobre esto en la página de claves API.
Comprobando el estado del archivo
Cuando se carga un archivo, se valida de forma asincrónica antes de que esté disponible en la aplicación web Instrumental, y este proceso puede rechazar el archivo. Dado que las solicitudes de carga regresan antes de que esto suceda, es posible que desee verificar mediante programación para saber si su archivo se validó correctamente.
Solicitar
Para hacer esto, realice una solicitud HTTPGET
https://api.instrumental.ai/api/v0/externalData/fileStatus?ids=FILE_ID
, reemplazando FILE_ID
con una cadena de ID de archivo devuelta por una solicitud ingestImage
. Puede solicitar el estado de varios archivos a la vez agregando varios parámetros ids
a la solicitud. Aquí hay un ejemplo usando cURL:
curl -XGET -H 'clave-api-instrumental: YOUR_API_KEY' 'https://api.instrumental.ai/api/v0/externalData/fileStatus?ids=FILE_ID_1&ids=FILE_ID_2'
(Si desea probar esto, asegúrese de reemplazar YOUR_API_KEY
con su clave API real y proporcione ID de archivos reales).
Respuesta
Si tiene éxito, la respuesta tendrá un código de estado HTTP de 200 y el cuerpo de la respuesta será un objeto JSON que asignará los ID del archivo de entrada a sus estados. Aquí tienes un ejemplo:
{
"estados": {
"e0Blm7EjlLQ2": "CARGADO",
"s5tZdX5qDuN5": "PENDIENTE_VALIDACIÓN"
}
}
El código de estado del archivo puede ser uno de los siguientes:
- PENDING_VALIDATION: El archivo se ha subido y la validación comenzará pronto o ya está en progreso.
- FAILED_VALIDATION: Se detectó que el archivo era malicioso o no cumplía otros requisitos, como comprobaciones de tipo de archivo.
- CARGADO: El archivo ha sido validado y está disponible en la aplicación web Instrumental.
Esta solicitud puede fallar por los motivos habituales mencionados anteriormente (por ejemplo, devolver un 401 si no se proporciona una clave API válida). Además, la solicitud fallará con un código de estado HTTP 400 si alguno de los ID de archivo proporcionados no es válido. En ese caso, el cuerpo de la respuesta tendrá la estructura { "code": "CODE", "msg": "Explanation" }
con un código de COULD_NOT_PARSE
(si la cadena de ID tiene un formato incorrecto) o FILE_NOT_FOUND
(si el ID no hace referencia a un archivo accesible).