Analítica e IA
Informes y analíticas
Obtén analíticas de conteo y series temporales desde la API de Rhombus: conteos de personas y vehículos, tendencias de ocupación, conteos de cruce de línea (umbral) y exportación a CSV.
En esta página
- Descripción general
- Requisitos previos
- Crear una serie temporal de conteo
- Campos de la solicitud
- Campos de la respuesta
- Informes heredados con cadenas de fecha
- Crear un panel de conteo de personas y ocupación
- Tendencia de ocupación en el tiempo
- Contar cruces de línea (conteos de umbral)
- Campos de la solicitud
- Campos de la respuesta
- Exportar datos de informes como CSV
- Referencia de enumeraciones
- ReportType
- ReportInterval
- ReportScope
- CrossingObject
- Casos de uso
- Avanzado: analíticas con AI Scene Query
- Solución de problemas
- Próximos pasos
Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, escríbenos.
Descripción general
El Report Webservice de Rhombus convierte las detecciones de tus cámaras en analíticas agregadas y agrupadas por tiempo. En lugar de recorrer eventos individuales, solicitas un informe de conteo para un rango de tiempo y un intervalo, y Rhombus devuelve un punto de datos por cada segmento (bucket) con un conteo por tipo.
A través de la API, puedes:
- Crear series temporales de conteo de personas, vehículos, movimiento, rostros y otros tipos de detección a nivel de organización, ubicación o dispositivo
- Seguir conteos de personas y ocupación con las lecturas más recientes y tendencias de ocupación agrupadas
- Medir conteos de cruce de línea (umbral) de personas o vehículos que cruzan una línea configurada
- Exportar datos de informes como CSV para hojas de cálculo, herramientas de BI e informes de cumplimiento
Se aplican algunas convenciones en toda esta API:
- Las marcas de tiempo están en milisegundos epoch en los endpoints V2, de ocupación y de umbral (
startTimeMs/endTimeMs). El endpoint heredado v1getCountReportusa cadenas de fecha"YYYY-MM-DD"en su lugar. - Los informes se describen con tres enumeraciones: un tipo de informe (qué contar), un intervalo (tamaño del segmento) y un alcance (organización, ubicación o dispositivo). Consulta las tablas de referencia más abajo.
- No existe un endpoint para "listar tipos de informe". Los tipos disponibles son fijos y están documentados en la tabla
ReportType.
Requisitos previos
Antes de comenzar, asegúrate de tener:
- Una clave de API de Rhombus con permisos de informes (generada en la Consola de Rhombus en Configuración → Integraciones y recursos para desarrolladores → Tokens de API)
- Al menos una cámara desplegada y reportando las analíticas que deseas consultar (por ejemplo, una cámara con conteo de personas o LPR)
- El UUID de la organización, ubicación o dispositivo al que deseas limitar el informe
- Para la exportación a CSV y los feeds de auditoría/diagnóstico: el permiso
REPORT_ADMINISTRATIONen la clave de API
Todas las solicitudes son POST, envían un cuerpo JSON y usan la URL base https://api2.rhombussystems.com con estos encabezados:
x-auth-scheme: api-token
x-auth-apikey: YOUR_API_KEY
Content-Type: application/jsonCrear una serie temporal de conteo
getCountReportV2 es el endpoint principal de informes. Proporciona un rango de tiempo en milisegundos epoch, un intervalo, un alcance y uno o más tipos de informe. Rhombus devuelve un punto de datos por cada segmento del intervalo, cada uno con un eventCountMap indexado por tipo de informe.
Este ejemplo obtiene conteos horarios de personas y vehículos para una sola ubicación durante las últimas 24 horas.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
now_ms = int(time.time() * 1000)
one_day_ago_ms = now_ms - (24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/report/getCountReportV2",
headers=headers,
json={
"scope": "LOCATION",
"uuid": "YOUR_LOCATION_UUID",
"types": ["PEOPLE", "VEHICLES"],
"interval": "HOURLY",
"startTimeMs": one_day_ago_ms,
"endTimeMs": now_ms,
"timeZone": "America/Los_Angeles"
}
)
data = response.json()
for point in data.get("timeSeriesDataPoints", []):
counts = point.get("eventCountMap", {})
print(f"{point.get('dateLocal')}: "
f"people={counts.get('PEOPLE', 0)}, "
f"vehicles={counts.get('VEHICLES', 0)}")const now = Date.now();
const oneDayAgo = now - (24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/report/getCountReportV2', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
scope: 'LOCATION',
uuid: 'YOUR_LOCATION_UUID',
types: ['PEOPLE', 'VEHICLES'],
interval: 'HOURLY',
startTimeMs: oneDayAgo,
endTimeMs: now,
timeZone: 'America/Los_Angeles'
})
});
const data = await response.json();
for (const point of data.timeSeriesDataPoints || []) {
const counts = point.eventCountMap || {};
console.log(`${point.dateLocal}: people=${counts.PEOPLE || 0}, vehicles=${counts.VEHICLES || 0}`);
}curl -X POST https://api2.rhombussystems.com/api/report/getCountReportV2 \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"scope": "LOCATION",
"uuid": "YOUR_LOCATION_UUID",
"types": ["PEOPLE", "VEHICLES"],
"interval": "HOURLY",
"startTimeMs": 1712620800000,
"endTimeMs": 1712707200000,
"timeZone": "America/Los_Angeles"
}'Campos de la solicitud
Nivel de agregación. Uno de ORG, LOCATION, DEVICE o REGION. Consulta la tabla ReportScope.
El UUID de la ubicación o dispositivo que coincide con tu scope. Omítelo con scope: "ORG" para informar sobre toda la organización.
Uno o más tipos de informe a contar. Consulta la tabla ReportType.
Tamaño del segmento de cada punto de datos. Uno de MINUTELY, QUARTERHOURLY, HOURLY, DAILY, WEEKLY, MONTHLY. Consulta la tabla ReportInterval.
Inicio del rango, en milisegundos epoch.
Fin del rango, en milisegundos epoch.
Zona horaria IANA opcional (por ejemplo, America/New_York). Controla dónde caen los límites de los segmentos del intervalo y rellena dateLocal. Por defecto es UTC cuando se omite.
El endpoint V2 acepta los campos heredados startDate / endDate como cadenas, pero están obsoletos. Usa en su lugar los campos en milisegundos epoch startTimeMs / endTimeMs.
Campos de la respuesta
Una entrada por cada segmento del intervalo.
¿Necesitas un total único en lugar de una serie por segmentos? Llama a /api/report/getSummaryCountReport con los mismos startTimeMs, endTimeMs, interval, scope y un solo type.
Informes heredados con cadenas de fecha
El endpoint v1 /api/report/getCountReport es anterior a las marcas de tiempo en milisegundos epoch. Toma startDate y endDate como cadenas "YYYY-MM-DD" y un único type en lugar de un arreglo types. Prefiere getCountReportV2 para nuevas integraciones; usa v1 solo si ya dependes de su comportamiento con cadenas de fecha.
curl -X POST https://api2.rhombussystems.com/api/report/getCountReport \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"scope": "LOCATION",
"uuid": "YOUR_LOCATION_UUID",
"type": "PEOPLE",
"interval": "DAILY",
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}'Crear un panel de conteo de personas y ocupación
Para un panel de ocupación, usa getOccupancyCountsV2 para una tendencia de ocupación agrupada en el tiempo y grafica junto a ella getCountReportV2 con types: ["PEOPLE"] para el tráfico de personas (consulta Crear una serie temporal de conteo).
Tendencia de ocupación en el tiempo
getOccupancyCountsV2 devuelve la ocupación agrupada de un dispositivo a lo largo de un rango de tiempo, usando el mismo modelo de intervalos que los informes de conteo.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
now_ms = int(time.time() * 1000)
one_day_ago_ms = now_ms - (24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/report/getOccupancyCountsV2",
headers=headers,
json={
"deviceUuid": "YOUR_CAMERA_UUID",
"startTimeMs": one_day_ago_ms,
"endTimeMs": now_ms,
"interval": "HOURLY"
}
)
data = response.json()
for point in data.get("timeSeriesDataPoints", []):
print(f"{point.get('dateLocal')}: {point.get('eventCountMap')}")const now = Date.now();
const oneDayAgo = now - (24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/report/getOccupancyCountsV2', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
deviceUuid: 'YOUR_CAMERA_UUID',
startTimeMs: oneDayAgo,
endTimeMs: now,
interval: 'HOURLY'
})
});
const data = await response.json();
for (const point of data.timeSeriesDataPoints || []) {
console.log(`${point.dateLocal}: ${JSON.stringify(point.eventCountMap)}`);
}curl -X POST https://api2.rhombussystems.com/api/report/getOccupancyCountsV2 \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"deviceUuid": "YOUR_CAMERA_UUID",
"startTimeMs": 1712620800000,
"endTimeMs": 1712707200000,
"interval": "HOURLY"
}'Los timeSeriesDataPoints de la respuesta llevan los mismos campos dateUtc, dateLocal, eventCountMap y reportingDevicesMap que los informes de conteo, además de un timestampMs (inicio del segmento en milisegundos epoch) y un approximateTimestampMsMap.
Este informe de ocupación se deriva de las analíticas de la cámara mediante el Report Webservice. Es distinto del Occupancy Webservice (/api/occupancy/*), que lee sensores físicos BLE y de movimiento, un producto aparte.
Contar cruces de línea (conteos de umbral)
Cuando una cámara tiene configurada una línea de cruce, Rhombus cuenta los objetos que la cruzan. getThresholdCrossingCounts devuelve esos conteos agrupados en el tiempo para uno o más dispositivos, filtrados a una sola clase de objeto.
El campo dailyResetTimeMinute establece el minuto del día (0–1439, en la hora local del dispositivo) en el que el conteo diario acumulado se reinicia: útil para alinear los conteos a una jornada comercial en lugar de a la medianoche.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
now_ms = int(time.time() * 1000)
one_week_ago_ms = now_ms - (7 * 24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/report/getThresholdCrossingCounts",
headers=headers,
json={
"devices": ["YOUR_CAMERA_UUID"],
"startTimeMs": one_week_ago_ms,
"endTimeMs": now_ms,
"crossingObject": "HUMAN",
"dailyResetTimeMinute": 0
}
)
data = response.json()
for entry in data.get("counts", []):
print(f"[{entry.get('timestampMs')}] crossings={entry.get('count')}")const now = Date.now();
const oneWeekAgo = now - (7 * 24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/report/getThresholdCrossingCounts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
devices: ['YOUR_CAMERA_UUID'],
startTimeMs: oneWeekAgo,
endTimeMs: now,
crossingObject: 'HUMAN',
dailyResetTimeMinute: 0
})
});
const data = await response.json();
for (const entry of data.counts || []) {
console.log(`[${entry.timestampMs}] crossings=${entry.count}`);
}curl -X POST https://api2.rhombussystems.com/api/report/getThresholdCrossingCounts \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"devices": ["YOUR_CAMERA_UUID"],
"startTimeMs": 1712016000000,
"endTimeMs": 1712620800000,
"crossingObject": "HUMAN",
"dailyResetTimeMinute": 0
}'Campos de la solicitud
Uno o más UUID de cámaras a incluir en los conteos.
Inicio del rango, en milisegundos epoch.
Fin del rango, en milisegundos epoch.
La clase de objeto a contar. Los valores comunes son HUMAN y VEHICLE. Consulta la tabla CrossingObject.
Minuto del día (0–1439) en el que se reinicia el conteo diario, en la hora local del dispositivo.
Campos de la respuesta
Exportar datos de informes como CSV
El Export Webservice transmite los datos de informes como CSV (text/csv) en lugar de JSON. No existe exportación a PDF: CSV es el único formato de exportación.
Los endpoints de exportación (y los feeds de auditoría/diagnóstico) requieren el permiso REPORT_ADMINISTRATION en tu clave de API. Sin él, estas llamadas se rechazan.
/api/export/countReports refleja los parámetros del informe de conteo pero devuelve un flujo CSV. Ten en cuenta que la exportación toma un único campo type, no un arreglo types, y tanto startTimeMs como endTimeMs son obligatorios.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
now_ms = int(time.time() * 1000)
thirty_days_ago_ms = now_ms - (30 * 24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/export/countReports",
headers=headers,
json={
"scope": "LOCATION",
"uuidList": ["YOUR_LOCATION_UUID"],
"type": "PEOPLE",
"interval": "DAILY",
"startTimeMs": thirty_days_ago_ms,
"endTimeMs": now_ms,
"timeZone": "America/Los_Angeles"
}
)
# La respuesta es texto CSV, no JSON
with open("people_count_report.csv", "w") as f:
f.write(response.text)
print("Informe exportado a people_count_report.csv")const now = Date.now();
const thirtyDaysAgo = now - (30 * 24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/export/countReports', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
scope: 'LOCATION',
uuidList: ['YOUR_LOCATION_UUID'],
type: 'PEOPLE',
interval: 'DAILY',
startTimeMs: thirtyDaysAgo,
endTimeMs: now,
timeZone: 'America/Los_Angeles'
})
});
// La respuesta es texto CSV, no JSON
const csv = await response.text();
console.log(csv);curl -X POST https://api2.rhombussystems.com/api/export/countReports \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"scope": "LOCATION",
"uuidList": ["YOUR_LOCATION_UUID"],
"type": "PEOPLE",
"interval": "DAILY",
"startTimeMs": 1710028800000,
"endTimeMs": 1712620800000,
"timeZone": "America/Los_Angeles"
}' \
-o people_count_report.csvComo el cuerpo de la respuesta es CSV, léelo como texto (response.text / .text()) o escríbelo directamente en un archivo con la opción -o en cURL. No intentes analizarlo como JSON.
Para exportar lecturas de conteo de personas sin agregar en lugar de informes agregados, usa /api/export/peopleCountEvents con un startInterval y un endInterval (milisegundos epoch). Devuelve CSV de la misma manera.
Referencia de enumeraciones
Los informes se describen con un pequeño conjunto de enumeraciones fijas. No hay ningún endpoint que las liste en tiempo de ejecución: los valores siguientes son el conjunto completo.
ReportType
Valores aceptados por el arreglo types (V2) y el campo único type (v1 y exportación).
| Valor | Cuenta |
|---|---|
CROWD | Detecciones de densidad de multitud |
PEOPLE | Detecciones de personas / conteo de personas |
FACES | Detecciones de rostros |
MOTION | Eventos de movimiento |
BANDWIDTH | Uso de ancho de banda del dispositivo |
VEHICLES | Detecciones de vehículos |
LICENSEPLATES | Lecturas de matrículas |
ALERTS | Eventos de alerta / política |
AM_VERIFICATION | Verificaciones de monitoreo de alarmas |
DWELL | Detecciones de tiempo de permanencia |
ReportInterval
Tamaño del segmento de cada punto de datos.
| Valor | Segmento |
|---|---|
MINUTELY | Por minuto |
QUARTERHOURLY | Cada 15 minutos |
HOURLY | Por hora |
DAILY | Por día |
WEEKLY | Por semana |
MONTHLY | Por mes |
ReportScope
Nivel de agregación de un informe de conteo. Proporciona un uuid correspondiente para LOCATION, DEVICE o REGION; omítelo para ORG.
| Valor | Agrega sobre |
|---|---|
ORG | Toda la organización |
LOCATION | Una sola ubicación |
DEVICE | Un solo dispositivo |
REGION | Una región configurada |
CrossingObject
Clase de objeto para getThresholdCrossingCounts.
| Valor | Objeto |
|---|---|
HUMAN | Personas |
VEHICLE | Vehículos |
FACE | Rostros |
LPR | Matrículas |
POSE | Detecciones de pose |
CLIP_EMBED | Coincidencias por embedding visual |
UNKNOWN | Sin clasificar |
Casos de uso
- Paneles de tráfico peatonal: grafica conteos horarios o diarios de
PEOPLEpor ubicación congetCountReportV2para comparar tiendas o seguir tendencias en el tiempo. - Monitoreo de ocupación: grafica los intervalos de
getOccupancyCountsV2para mostrar la ocupación a lo largo del día y compararla con periodos anteriores. - Conteo de entradas y carriles: usa
getThresholdCrossingCountsconcrossingObject: "HUMAN"o"VEHICLE"para contar personas por una puerta o vehículos por un carril. - Informes programados: ejecuta
/api/export/countReportscon un cron y coloca el CSV en una herramienta de BI o un almacén de datos para informes semanales y mensuales.
Avanzado: analíticas con AI Scene Query
Rhombus también ofrece Scene Query, una función de IA que cuenta eventos personalizados definidos en lenguaje natural (por ejemplo, "montacargas sin señalador"). Scene Query se configura mediante los endpoints /api/scenequery/* y se informa a través de /api/report/getCustomEventsReport. Es una capacidad distinta y con licencia, más que parte del flujo de trabajo principal de informes anterior: trátala como una extensión opcional cuando los tipos de informe estándar no capturen lo que necesitas medir.
Solución de problemas
timeSeriesDataPoints vacío o conteos todos en cero
Confirma que el dispositivo realmente produce la analítica que solicitaste: una cámara sin conteo de personas habilitado no devuelve datos de PEOPLE. Verifica también que tu rango de tiempo esté en milisegundos epoch (no segundos) y que el par scope/uuid sea correcto.
Los segmentos están desfasados respecto a la hora local
Establece el campo timeZone en la zona IANA correspondiente (por ejemplo, America/Chicago). Sin él, los límites de los segmentos y dateLocal caen en UTC.
La solicitud de exportación es rechazada
La exportación a CSV requiere el permiso REPORT_ADMINISTRATION. Revisa los permisos de la clave de API en la Consola de Rhombus y recuerda que el cuerpo de la exportación usa un único campo type en lugar del arreglo types que usa getCountReportV2.
La respuesta de exportación parece JSON corrupto
Los endpoints de exportación devuelven text/csv, no JSON. Lee la respuesta como texto o escríbela en un archivo en lugar de llamar a .json().
Próximos pasos
Registra personas, consulta eventos de rostros y profundiza en las analíticas de conteo de personas
Consulta lecturas de matrículas y detecciones de vehículos que alimentan los tipos de informe de vehículos
Explora los esquemas completos de solicitud y respuesta de cada endpoint de informe y exportación