curl --request GET \
--url https://api.bookovia.com/v1/analytics/harsh-events/{trip_id} \
--header 'X-API-Key: <api-key>'{
"error": {
"code": "insufficient_sensor_data",
"message": "Insufficient accelerometer data for harsh event analysis",
"details": "Trip must have high-frequency sensor data for accurate harsh event detection"
}
}
Detailed analysis of harsh driving events including acceleration, braking, cornering incidents with contextual information and prevention insights
curl --request GET \
--url https://api.bookovia.com/v1/analytics/harsh-events/{trip_id} \
--header 'X-API-Key: <api-key>'{
"error": {
"code": "insufficient_sensor_data",
"message": "Insufficient accelerometer data for harsh event analysis",
"details": "Trip must have high-frequency sensor data for accurate harsh event detection"
}
}
Documentation Index
Fetch the complete documentation index at: https://docs.bookovia.com/llms.txt
Use this file to discover all available pages before exploring further.
X-API-Key header.
Required permissions: analytics:read
curl -X GET "https://api.bookovia.com/v1/analytics/harsh-events/trip_1234567890abcdef?include_context=true&include_prevention=true" \
-H "X-API-Key: bkv_test_your_api_key_here"
Show event_summary properties
Show harsh_event properties
Show pattern_analysis properties
{
"trip_id": "trip_1234567890abcdef",
"analysis_timestamp": "2024-04-13T12:45:00Z",
"driver_id": "driver_456",
"vehicle_id": "vehicle_123",
"event_summary": {
"total_events": 5,
"events_by_type": {
"harsh_braking": 3,
"harsh_acceleration": 1,
"harsh_cornering": 1,
"rapid_direction_change": 0
},
"events_by_severity": {
"low": 1,
"moderate": 3,
"high": 1,
"critical": 0
},
"event_rate": {
"events_per_km": 0.11,
"events_per_minute": 0.048
},
"severity_distribution": {
"low": 20.0,
"moderate": 60.0,
"high": 20.0,
"critical": 0.0
}
},
"harsh_events": [
{
"event_id": "evt_harsh_brake_001",
"event_type": "harsh_braking",
"severity": "high",
"timestamp": "2024-04-13T11:22:15.234Z",
"duration_seconds": 2.1,
"location": {
"latitude": 40.7298,
"longitude": -73.9973,
"address": "Broadway & 14th St, New York, NY",
"road_type": "city_street",
"speed_limit_kmh": 40
},
"event_metrics": {
"peak_deceleration_g": -0.68,
"average_deceleration_g": -0.52,
"deceleration_jerk": -2.3,
"speed_before_kmh": 38,
"speed_after_kmh": 12,
"speed_change_kmh": 26,
"brake_pressure_max": 85,
"abs_activation": false,
"wheel_lock_detected": false
},
"contextual_factors": {
"traffic_conditions": "heavy",
"weather": "clear",
"visibility": "good",
"road_surface": "dry",
"time_of_day": "morning_rush",
"preceding_vehicle": {
"present": true,
"distance_meters": 8.2,
"relative_speed_kmh": -15
},
"traffic_signal": {
"present": true,
"status": "yellow_to_red",
"distance_to_line_meters": 25
},
"pedestrian_activity": "moderate"
},
"trigger_analysis": {
"primary_trigger": "traffic_signal_change",
"contributing_factors": [
"close_following_distance",
"late_recognition",
"heavy_traffic"
],
"predictability": "moderate",
"avoidability": "high"
},
"impact_assessment": {
"safety_impact": {
"collision_risk": "moderate",
"passenger_comfort": "significantly_affected",
"following_vehicle_impact": "minimal"
},
"vehicle_impact": {
"brake_wear": "moderate",
"tire_wear": "minimal",
"fuel_efficiency_impact": "low"
},
"operational_impact": {
"schedule_delay": "negligible",
"passenger_experience": "negative",
"route_efficiency": "minimal_impact"
}
},
"prevention_analysis": {
"root_cause": "insufficient_scanning_distance",
"preventive_actions": [
"increase_scanning_distance_to_12_seconds",
"maintain_3_second_following_distance",
"anticipate_traffic_signal_timing"
],
"training_focus": [
"hazard_perception",
"following_distance_management",
"intersection_approach_techniques"
],
"prevention_difficulty": "moderate",
"recurrence_probability": "medium"
}
},
{
"event_id": "evt_harsh_accel_001",
"event_type": "harsh_acceleration",
"severity": "moderate",
"timestamp": "2024-04-13T11:35:42.156Z",
"duration_seconds": 3.8,
"location": {
"latitude": 40.7412,
"longitude": -73.9897,
"address": "FDR Drive Northbound, New York, NY",
"road_type": "highway_onramp",
"speed_limit_kmh": 80
},
"event_metrics": {
"peak_acceleration_g": 0.45,
"average_acceleration_g": 0.31,
"acceleration_jerk": 1.8,
"speed_before_kmh": 25,
"speed_after_kmh": 65,
"speed_change_kmh": 40,
"throttle_position_max": 78,
"engine_load_max": 82,
"traction_loss_detected": false
},
"contextual_factors": {
"traffic_conditions": "light",
"weather": "clear",
"road_surface": "dry",
"merge_situation": {
"merging_required": true,
"gap_size_seconds": 2.8,
"traffic_speed_kmh": 70,
"merge_urgency": "moderate"
},
"gradient": {
"grade_percentage": 3.2,
"direction": "uphill"
}
},
"trigger_analysis": {
"primary_trigger": "highway_merge_acceleration",
"contributing_factors": [
"small_merge_gap",
"uphill_gradient",
"traffic_speed_differential"
],
"predictability": "high",
"avoidability": "moderate"
},
"impact_assessment": {
"safety_impact": {
"merge_safety": "acceptable",
"passenger_comfort": "mildly_affected",
"tire_traction": "good"
},
"vehicle_impact": {
"engine_stress": "moderate",
"fuel_consumption": "increased",
"transmission_wear": "minimal"
},
"operational_impact": {
"merge_success": "achieved",
"traffic_flow_impact": "neutral"
}
},
"prevention_analysis": {
"root_cause": "merge_gap_management",
"preventive_actions": [
"earlier_merge_preparation",
"gradual_acceleration_over_longer_distance",
"better_gap_selection"
],
"training_focus": [
"merge_techniques",
"acceleration_modulation",
"traffic_gap_assessment"
],
"prevention_difficulty": "low",
"recurrence_probability": "low"
}
}
],
"pattern_analysis": {
"temporal_patterns": {
"peak_occurrence_times": [
"morning_rush_hour",
"evening_rush_hour"
],
"event_frequency_by_hour": {
"07:00-08:00": 0,
"08:00-09:00": 1,
"09:00-10:00": 0,
"10:00-11:00": 1,
"11:00-12:00": 3,
"12:00-13:00": 0
},
"day_of_week_pattern": "weekday_concentrated"
},
"location_clusters": [
{
"cluster_id": "cluster_downtown_intersections",
"center_location": {
"latitude": 40.7295,
"longitude": -73.9965
},
"radius_meters": 500,
"events_count": 3,
"dominant_event_type": "harsh_braking",
"common_characteristics": [
"traffic_signal_intersections",
"heavy_pedestrian_traffic",
"frequent_lane_changes"
]
}
],
"trigger_analysis": {
"most_common_triggers": [
{
"trigger": "traffic_signal_change",
"frequency": 3,
"percentage": 60.0
},
{
"trigger": "merge_situation",
"frequency": 1,
"percentage": 20.0
},
{
"trigger": "pedestrian_crossing",
"frequency": 1,
"percentage": 20.0
}
],
"environmental_correlations": {
"weather_correlation": "clear_weather_predominant",
"traffic_correlation": "heavy_traffic_increases_events",
"time_correlation": "rush_hours_show_higher_frequency"
}
},
"correlation_analysis": {
"event_type_correlations": {
"harsh_braking_following_acceleration": 0.2,
"location_based_clustering": 0.7,
"time_based_clustering": 0.5
},
"severity_factors": {
"traffic_density": 0.65,
"speed_differential": 0.58,
"following_distance": -0.72
}
}
},
"prevention_recommendations": {
"immediate_actions": [
{
"priority": "high",
"category": "following_distance",
"action": "Maintain minimum 3-second following distance in all conditions",
"target_reduction": "50% reduction in harsh braking events"
},
{
"priority": "medium",
"category": "intersection_approach",
"action": "Begin slowing 200 meters before intersections with traffic signals",
"target_reduction": "30% reduction in signal-related harsh braking"
}
],
"training_recommendations": [
{
"training_type": "hazard_perception",
"duration": "2 hours",
"frequency": "monthly",
"focus_areas": [
"scanning_techniques",
"anticipation_skills",
"risk_assessment"
]
},
{
"training_type": "smooth_driving_techniques",
"duration": "1 hour",
"frequency": "bi_weekly",
"focus_areas": [
"gradual_input_application",
"momentum_management",
"efficiency_optimization"
]
}
],
"technology_solutions": [
{
"solution": "forward_collision_warning",
"implementation": "dashboard_alerts",
"effectiveness": "high"
},
{
"solution": "following_distance_monitoring",
"implementation": "continuous_feedback",
"effectiveness": "moderate"
}
],
"behavioral_interventions": [
{
"intervention": "real_time_coaching",
"method": "audio_feedback_during_events",
"frequency": "immediate"
},
{
"intervention": "post_trip_review",
"method": "event_replay_and_discussion",
"frequency": "after_each_trip_with_events"
}
]
},
"comparative_analysis": {
"vs_driver_average": {
"events_per_km": {
"current_trip": 0.11,
"driver_average": 0.08,
"variance": "+37.5%"
},
"severity_distribution": {
"current_trip_high_severity": 20.0,
"driver_average_high_severity": 12.0,
"variance": "+66.7%"
}
},
"vs_fleet_benchmark": {
"events_per_km": {
"current_trip": 0.11,
"fleet_average": 0.06,
"variance": "+83.3%"
},
"improvement_potential": "significant"
}
}
}
{
"error": {
"code": "insufficient_sensor_data",
"message": "Insufficient accelerometer data for harsh event analysis",
"details": "Trip must have high-frequency sensor data for accurate harsh event detection"
}
}
import Bookovia from '@bookovia/javascript-sdk';
const client = new Bookovia('bkv_test_your_api_key');
// Comprehensive harsh events analysis
const harshEventsAnalysis = await client.analytics.analyzeHarshEvents('trip_1234567890abcdef', {
eventTypes: ['harsh_acceleration', 'harsh_braking', 'harsh_cornering'],
severityThreshold: 'moderate',
includeContext: true,
includePrevention: true,
groupByLocation: true
});
console.log(`Total Events: ${harshEventsAnalysis.eventSummary.totalEvents}`);
console.log(`Event Rate: ${harshEventsAnalysis.eventSummary.eventRate.eventsPerKm} events/km`);
// Analyze event patterns
const analyzeEventPatterns = (eventsData) => {
const patterns = {
mostCommonType: '',
highestSeverityTime: '',
riskiestLocations: [],
preventableEvents: 0
};
// Find most common event type
const typeFrequency = eventsData.eventSummary.eventsByType;
patterns.mostCommonType = Object.keys(typeFrequency).reduce((a, b) =>
typeFrequency[a] > typeFrequency[b] ? a : b
);
// Analyze prevention potential
patterns.preventableEvents = eventsData.harshEvents.filter(event =>
event.preventionAnalysis.avoidability === 'high'
).length;
// Identify risky locations
if (eventsData.patternAnalysis.locationClusters) {
patterns.riskiestLocations = eventsData.patternAnalysis.locationClusters
.sort((a, b) => b.eventsCount - a.eventsCount)
.slice(0, 3);
}
return patterns;
};
// Real-time harsh event monitoring system
class HarshEventMonitor {
constructor(client) {
this.client = client;
this.eventThresholds = {
moderate: { maxPerKm: 0.15, maxPerTrip: 5 },
high: { maxPerKm: 0.08, maxPerTrip: 3 },
critical: { maxPerKm: 0.05, maxPerTrip: 2 }
};
}
async monitorTripEvents(tripId, alertCallback) {
try {
const analysis = await this.client.analytics.analyzeHarshEvents(tripId, {
severityThreshold: 'low',
includeContext: true,
includePrevention: true
});
// Check for alert conditions
const alerts = this.generateAlerts(analysis);
if (alerts.length > 0 && alertCallback) {
alerts.forEach(alert => alertCallback(alert));
}
return {
tripId,
eventsSummary: analysis.eventSummary,
alerts: alerts,
riskLevel: this.assessRiskLevel(analysis),
recommendations: this.prioritizeRecommendations(analysis.preventionRecommendations)
};
} catch (error) {
console.error(`Failed to monitor events for trip ${tripId}:`, error);
return { error: error.message };
}
}
generateAlerts(analysis) {
const alerts = [];
const summary = analysis.eventSummary;
// High event rate alert
if (summary.eventRate.eventsPerKm > this.eventThresholds.moderate.maxPerKm) {
alerts.push({
type: 'high_event_rate',
severity: summary.eventRate.eventsPerKm > this.eventThresholds.critical.maxPerKm ? 'critical' : 'warning',
message: `High harsh event rate: ${summary.eventRate.eventsPerKm.toFixed(2)} events/km`,
recommendation: 'Immediate coaching intervention recommended'
});
}
// Severe event alert
const severeEvents = summary.eventsBySeverity.high + summary.eventsBySeverity.critical;
if (severeEvents > 0) {
alerts.push({
type: 'severe_events',
severity: summary.eventsBySeverity.critical > 0 ? 'critical' : 'high',
message: `${severeEvents} severe harsh events detected`,
recommendation: 'Review driving techniques and provide targeted training'
});
}
// Pattern-based alerts
if (analysis.patternAnalysis?.locationClusters?.length > 0) {
alerts.push({
type: 'location_pattern',
severity: 'medium',
message: 'Multiple events detected in same location area',
recommendation: 'Review specific location hazards and route planning'
});
}
return alerts;
}
assessRiskLevel(analysis) {
const summary = analysis.eventSummary;
const eventsPerKm = summary.eventRate.eventsPerKm;
const severityScore = (summary.eventsBySeverity.critical * 4) +
(summary.eventsBySeverity.high * 3) +
(summary.eventsBySeverity.moderate * 2) +
(summary.eventsBySeverity.low * 1);
if (eventsPerKm > 0.15 || severityScore > 10) {
return 'high';
} else if (eventsPerKm > 0.08 || severityScore > 5) {
return 'medium';
} else {
return 'low';
}
}
prioritizeRecommendations(recommendations) {
if (!recommendations) return [];
const prioritized = [];
// Add immediate actions first
if (recommendations.immediateActions) {
prioritized.push(...recommendations.immediateActions
.sort((a, b) => {
const priorityOrder = { 'high': 0, 'medium': 1, 'low': 2 };
return priorityOrder[a.priority] - priorityOrder[b.priority];
})
);
}
// Add training recommendations
if (recommendations.trainingRecommendations) {
prioritized.push(...recommendations.trainingRecommendations);
}
return prioritized.slice(0, 5); // Top 5 recommendations
}
}
// Fleet-wide harsh events dashboard
const createFleetEventsDashboard = async (vehicleIds) => {
const fleetData = {
totalEvents: 0,
eventsByVehicle: {},
highRiskVehicles: [],
commonPatterns: {},
fleetRecommendations: []
};
for (const vehicleId of vehicleIds) {
try {
// Get recent trips for the vehicle
const trips = await client.trips.list({
vehicleId,
status: 'completed',
limit: 10
});
const vehicleEvents = [];
for (const trip of trips.trips) {
const analysis = await client.analytics.analyzeHarshEvents(trip.tripId, {
severityThreshold: 'low'
});
vehicleEvents.push({
tripId: trip.tripId,
events: analysis.eventSummary.totalEvents,
eventRate: analysis.eventSummary.eventRate.eventsPerKm,
severityDistribution: analysis.eventSummary.eventsBySeverity
});
}
// Calculate vehicle summary
const avgEventRate = vehicleEvents.reduce((sum, ve) => sum + ve.eventRate, 0) / vehicleEvents.length;
fleetData.eventsByVehicle[vehicleId] = {
avgEventRate,
totalTripsAnalyzed: vehicleEvents.length,
riskLevel: avgEventRate > 0.1 ? 'high' : avgEventRate > 0.05 ? 'medium' : 'low'
};
// Identify high-risk vehicles
if (avgEventRate > 0.1) {
fleetData.highRiskVehicles.push({
vehicleId,
avgEventRate,
priority: avgEventRate > 0.2 ? 'critical' : 'high'
});
}
fleetData.totalEvents += vehicleEvents.reduce((sum, ve) => sum + ve.events, 0);
} catch (error) {
console.error(`Failed to analyze events for vehicle ${vehicleId}:`, error);
}
}
// Generate fleet-wide recommendations
fleetData.fleetRecommendations = generateFleetRecommendations(fleetData);
return fleetData;
};
const generateFleetRecommendations = (fleetData) => {
const recommendations = [];
if (fleetData.highRiskVehicles.length > 0) {
recommendations.push({
type: 'immediate_intervention',
priority: 'high',
title: 'Address high-risk vehicles',
description: `${fleetData.highRiskVehicles.length} vehicles show high harsh event rates`,
action: 'Implement immediate driver coaching and vehicle inspection'
});
}
const fleetAvgRate = Object.values(fleetData.eventsByVehicle)
.reduce((sum, v) => sum + v.avgEventRate, 0) / Object.keys(fleetData.eventsByVehicle).length;
if (fleetAvgRate > 0.08) {
recommendations.push({
type: 'fleet_training',
priority: 'medium',
title: 'Fleet-wide safety training',
description: `Fleet average event rate (${fleetAvgRate.toFixed(3)}) exceeds recommended threshold`,
action: 'Implement comprehensive defensive driving program'
});
}
return recommendations;
};
// Usage examples
const monitor = new HarshEventMonitor(client);
// Monitor specific trip
const monitoringResult = await monitor.monitorTripEvents('trip_123', (alert) => {
console.log(`ALERT: ${alert.type} - ${alert.message}`);
});
// Create fleet dashboard
const fleetDashboard = await createFleetEventsDashboard(['vehicle_001', 'vehicle_002', 'vehicle_003']);
console.log(`Fleet Analysis: ${fleetDashboard.totalEvents} total events across ${Object.keys(fleetDashboard.eventsByVehicle).length} vehicles`);
// Real-time harsh events monitoring and intervention system
class RealTimeSafetySystem {
constructor(client, interventionThresholds) {
this.client = client;
this.thresholds = interventionThresholds || {
immediate: { eventsPerKm: 0.3, severityWeight: 8 },
urgent: { eventsPerKm: 0.2, severityWeight: 6 },
standard: { eventsPerKm: 0.1, severityWeight: 4 }
};
this.activeMonitoring = new Map();
}
async startTripMonitoring(tripId, driverId, interventionCallbacks = {}) {
const monitoringSession = {
tripId,
driverId,
startTime: new Date(),
eventHistory: [],
interventionLevel: 'none',
callbacks: interventionCallbacks
};
this.activeMonitoring.set(tripId, monitoringSession);
// Start periodic monitoring
const monitoringInterval = setInterval(async () => {
await this.checkTripEvents(tripId);
}, 30000); // Check every 30 seconds
monitoringSession.intervalId = monitoringInterval;
return monitoringSession;
}
async checkTripEvents(tripId) {
const session = this.activeMonitoring.get(tripId);
if (!session) return;
try {
const eventsAnalysis = await this.client.analytics.analyzeHarshEvents(tripId, {
severityThreshold: 'low',
includeContext: true,
includePrevention: true
});
const newEvents = this.identifyNewEvents(session.eventHistory, eventsAnalysis.harshEvents);
if (newEvents.length > 0) {
// Update session with new events
session.eventHistory.push(...newEvents);
// Assess intervention need
const interventionDecision = this.assessInterventionNeed(session, eventsAnalysis);
if (interventionDecision.required) {
await this.triggerIntervention(session, interventionDecision, newEvents);
}
}
} catch (error) {
console.error(`Failed to monitor events for trip ${tripId}:`, error);
}
}
identifyNewEvents(existingEvents, currentEvents) {
const existingIds = new Set(existingEvents.map(e => e.eventId));
return currentEvents.filter(event => !existingIds.has(event.eventId));
}
assessInterventionNeed(session, eventsAnalysis) {
const summary = eventsAnalysis.eventSummary;
const eventRate = summary.eventRate.eventsPerKm;
// Calculate severity weight
const severityWeight =
(summary.eventsBySeverity.critical * 4) +
(summary.eventsBySeverity.high * 3) +
(summary.eventsBySeverity.moderate * 2) +
(summary.eventsBySeverity.low * 1);
let interventionLevel = 'none';
let interventionType = [];
// Determine intervention level
if (eventRate >= this.thresholds.immediate.eventsPerKm ||
severityWeight >= this.thresholds.immediate.severityWeight) {
interventionLevel = 'immediate';
interventionType = ['voice_alert', 'dispatcher_notification', 'route_guidance'];
} else if (eventRate >= this.thresholds.urgent.eventsPerKm ||
severityWeight >= this.thresholds.urgent.severityWeight) {
interventionLevel = 'urgent';
interventionType = ['in_app_alert', 'coaching_reminder'];
} else if (eventRate >= this.thresholds.standard.eventsPerKm ||
severityWeight >= this.thresholds.standard.severityWeight) {
interventionLevel = 'standard';
interventionType = ['gentle_reminder', 'score_feedback'];
}
return {
required: interventionLevel !== 'none',
level: interventionLevel,
types: interventionType,
reasoning: {
eventRate: eventRate,
severityWeight: severityWeight,
totalEvents: summary.totalEvents
}
};
}
async triggerIntervention(session, decision, newEvents) {
const intervention = {
timestamp: new Date(),
tripId: session.tripId,
driverId: session.driverId,
level: decision.level,
types: decision.types,
triggerEvents: newEvents,
reasoning: decision.reasoning
};
// Execute interventions based on type
for (const type of decision.types) {
await this.executeIntervention(type, intervention);
}
// Update session
session.interventionLevel = decision.level;
// Call custom callback if provided
if (session.callbacks.onIntervention) {
session.callbacks.onIntervention(intervention);
}
}
async executeIntervention(type, intervention) {
switch (type) {
case 'voice_alert':
await this.sendVoiceAlert(intervention);
break;
case 'dispatcher_notification':
await this.notifyDispatcher(intervention);
break;
case 'in_app_alert':
await this.sendInAppAlert(intervention);
break;
case 'coaching_reminder':
await this.sendCoachingReminder(intervention);
break;
case 'gentle_reminder':
await this.sendGentleReminder(intervention);
break;
case 'score_feedback':
await this.sendScoreFeedback(intervention);
break;
}
}
async sendVoiceAlert(intervention) {
// Implementation would integrate with vehicle's audio system
console.log(`🔊 VOICE ALERT for driver ${intervention.driverId}: Multiple harsh events detected. Please review your driving.`);
}
async notifyDispatcher(intervention) {
// Implementation would send alert to fleet dispatcher
console.log(`📞 DISPATCHER ALERT: Driver ${intervention.driverId} in trip ${intervention.tripId} needs immediate safety intervention`);
}
async sendInAppAlert(intervention) {
// Implementation would send push notification to driver app
console.log(`📱 IN-APP ALERT for ${intervention.driverId}: Safety coaching recommended based on recent driving patterns`);
}
stopTripMonitoring(tripId) {
const session = this.activeMonitoring.get(tripId);
if (session && session.intervalId) {
clearInterval(session.intervalId);
}
this.activeMonitoring.delete(tripId);
}
}
// Usage example
const safetySystem = new RealTimeSafetySystem(client, {
immediate: { eventsPerKm: 0.25, severityWeight: 7 },
urgent: { eventsPerKm: 0.15, severityWeight: 5 },
standard: { eventsPerKm: 0.08, severityWeight: 3 }
});
// Start monitoring a trip
const monitoringSession = await safetySystem.startTripMonitoring(
'trip_active_123',
'driver_456',
{
onIntervention: (intervention) => {
console.log(`Intervention triggered: ${intervention.level} level`);
// Custom handling - send to fleet management system, log to database, etc.
}
}
);
console.log('Real-time safety monitoring started for trip');
Data Quality Requirements
Contextual Analysis
// Context-aware event analysis
const analyzeEventInContext = (event, context) => {
let adjustedSeverity = event.severity;
// Adjust for weather conditions
if (context.weather === 'rain' || context.weather === 'snow') {
adjustedSeverity = adjustedSeverity === 'high' ? 'moderate' :
adjustedSeverity === 'moderate' ? 'low' : adjustedSeverity;
}
// Adjust for emergency situations
if (context.emergencyVehiclePresent) {
adjustedSeverity = 'justified';
}
return { ...event, adjustedSeverity, contextualFactors: context };
};
Proactive Coaching
Technology Integration
Was this page helpful?