### Geofence Creation and Management with API Fetch Source: https://context7.com/traccar/traccar-web/llms.txt Demonstrates creating circular and polygon geofences using POST requests to the /api/geofences endpoint. It also shows how to link geofences to devices and retrieve geofence data. This snippet assumes a running Traccar server and valid authentication. ```javascript // Create a circular geofence const circleGeofence = { name: 'Warehouse Zone', description: 'Main warehouse perimeter', area: 'CIRCLE (40.7128 -74.0060, 500)', // WKT format: lat lon, radius in meters attributes: { color: '#4CAF50', speedLimit: 20 } }; const createGeoResponse = await fetch('/api/geofences', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(circleGeofence) }); const createdGeofence = await createGeoResponse.json(); // Create a polygon geofence const polygonGeofence = { name: 'Delivery Area', area: 'POLYGON ((40.7128 -74.0060, 40.7138 -74.0050, 40.7148 -74.0070, 40.7128 -74.0060))', attributes: { color: '#2196F3' } }; await fetch('/api/geofences', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(polygonGeofence) }); // Link geofence to device await fetch('/api/permissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ deviceId: 123, geofenceId: createdGeofence.id }) }); // Get all geofences const geofencesResponse = await fetch('/api/geofences'); const geofences = await geofencesResponse.json(); // Get geofences for specific device const deviceGeoResponse = await fetch('/api/geofences?deviceId=123'); const deviceGeofences = await deviceGeoResponse.json(); // Listen for geofence events via WebSocket socket.onmessage = (event) => { const data = JSON.parse(event.data); if (data.events) { data.events.forEach(evt => { if (evt.type === 'geofenceEnter') { console.log(`Device ${evt.deviceId} entered geofence ${evt.geofenceId}`); } else if (evt.type === 'geofenceExit') { console.log(`Device ${evt.deviceId} exited geofence ${evt.geofenceId}`); } }); } }; ``` -------------------------------- ### Real-Time Position Tracking with WebSockets and API Fetch Source: https://context7.com/traccar/traccar-web/llms.txt Establishes a WebSocket connection to receive live device position updates and device status changes. It also demonstrates fetching the latest positions and historical position data using the API. This snippet requires a running Traccar server and a compatible WebSocket client environment. ```javascript // Establish WebSocket connection for real-time updates const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const socket = new WebSocket(`${protocol}//${window.location.host}/api/socket`); socket.onopen = () => { console.log('WebSocket connected'); }; socket.onmessage = (event) => { const data = JSON.parse(event.data); // Handle position updates if (data.positions) { data.positions.forEach(position => { console.log(`Device ${position.deviceId} at ${position.latitude}, ${position.longitude}`); console.log(`Speed: ${position.speed} knots, Course: ${position.course}°`); console.log(`Battery: ${position.attributes.batteryLevel}%`); console.log(`Address: ${position.address}`); }); } // Handle device status changes if (data.devices) { data.devices.forEach(device => { console.log(`Device ${device.id} status: ${device.status}`); // status: 'online', 'offline', or 'unknown' }); } // Handle events (alarms, geofence triggers, etc.) if (data.events) { data.events.forEach(event => { console.log(`Event: ${event.type} for device ${event.deviceId}`); if (event.type === 'alarm') { console.log(`Alarm type: ${event.attributes.alarm}`); } }); } }; socket.onerror = (error) => { console.error('WebSocket error:', error); }; socket.onclose = () => { console.log('WebSocket disconnected - reconnecting in 60s'); setTimeout(() => location.reload(), 60000); }; // Get latest positions for all devices const positionsResponse = await fetch('/api/positions'); const positions = await positionsResponse.json(); // Get position history for a device const from = new Date('2025-01-01T00:00:00Z').toISOString(); const to = new Date('2025-01-01T23:59:59Z').toISOString(); const historyResponse = await fetch( `/api/positions?deviceId=123&from=${from}&to=${to}` ); const history = await historyResponse.json(); console.log(`Retrieved ${history.length} historical positions`); ``` -------------------------------- ### Initialize and Render Map with Device Markers using MapLibre GL JS (React) Source: https://context7.com/traccar/traccar-web/llms.txt This JavaScript code snippet initializes a MapLibre GL map within a React component. It sets up the map container, style, center, and zoom level. It also configures sources and layers for displaying device markers, including clustering for a large number of devices. Dependencies include MapLibre GL JS and React hooks. ```javascript import maplibregl from 'maplibre-gl'; import { useEffect, useRef } from 'react'; import { useSelector } from 'react-redux'; // Initialize map const MapComponent = () => { const mapContainer = useRef(null); const map = useRef(null); const devices = useSelector((state) => state.devices.items); const positions = useSelector((state) => state.session.positions); useEffect(() => { if (map.current) return; // Initialize only once map.current = new maplibregl.Map({ container: mapContainer.current, style: 'https://tiles.locationiq.com/v3/streets/vector.json?key=YOUR_KEY', center: [-74.0060, 40.7128], // [lng, lat] zoom: 12 }); // Add navigation controls map.current.addControl(new maplibregl.NavigationControl()); // Wait for map to load map.current.on('load', () => { // Add device markers source map.current.addSource('devices', { type: 'geojson', data: { type: 'FeatureCollection', features: [] } }); // Add device markers layer map.current.addLayer({ id: 'device-markers', type: 'symbol', source: 'devices', layout: { 'icon-image': ['get', 'category'], // Use category for icon 'icon-size': 0.5, 'icon-rotate': ['get', 'rotation'], 'icon-rotation-alignment': 'map', 'icon-allow-overlap': true } }); // Add device clustering map.current.addSource('device-clusters', { type: 'geojson', data: { type: 'FeatureCollection', features: [] }, cluster: true, clusterMaxZoom: 14, clusterRadius: 50 }); map.current.addLayer({ id: 'clusters', type: 'circle', source: 'device-clusters', filter: ['has', 'point_count'], paint: { 'circle-color': '#2196F3', 'circle-radius': 20 } }); map.current.addLayer({ id: 'cluster-count', type: 'symbol', source: 'device-clusters', filter: ['has', 'point_count'], layout: { 'text-field': '{point_count_abbreviated}', 'text-size': 12 }, paint: { 'text-color': '#FFFFFF' } }); }); }, []); // Update device positions useEffect(() => { if (!map.current || !map.current.loaded()) return; const features = Object.values(devices).map((device) => { const position = positions[device.id]; if (!position) return null; return { type: 'Feature', geometry: { type: 'Point', coordinates: [position.longitude, position.latitude] }, properties: { id: device.id, name: device.name, category: device.category || 'default', status: device.status, rotation: position.course || 0 } }; }).filter(Boolean); const source = map.current.getSource('devices'); if (source) { source.setData({ type: 'FeatureCollection', features }); } }, [devices, positions]); // Add click handler for device markers useEffect(() => { if (!map.current) return; const handleClick = (e) => { const feature = e.features[0]; const deviceId = feature.properties.id; // Show popup new maplibregl.Popup() .setLngLat(e.lngLat) .setHTML( `

${feature.properties.name}

Status: ${feature.properties.status}

` ) .addTo(map.current); }; map.current.on('click', 'device-markers', handleClick); return () => { map.current.off('click', 'device-markers', handleClick); }; }, []); return
; }; export default MapComponent; ``` -------------------------------- ### Manage Drivers and QR Code Integration (JavaScript) Source: https://context7.com/traccar/traccar-web/llms.txt This JavaScript snippet outlines the process of managing drivers within Traccar, including creating driver profiles, linking them to devices, and generating QR codes for identification. It also shows how to handle driver identification when a device scans a QR code. This code is intended for a browser environment and relies on the Traccar API and a QR code generation library. ```javascript // Create driver const driver = { name: 'John Smith', uniqueId: 'DRV-1234', attributes: { phone: '+1234567890', licenseNumber: 'DL123456789', licenseExpiry: '2027-12-31' } }; const driverResponse = await fetch('/api/drivers', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(driver) }); const createdDriver = await driverResponse.json(); // Link driver to device await fetch('/api/permissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ deviceId: 123, driverId: createdDriver.id }) }); // Get drivers for device const deviceDriversResponse = await fetch('/api/drivers?deviceId=123'); const deviceDrivers = await deviceDriversResponse.json(); // Generate QR code for driver (browser-side) import QRCode from 'react-qr-code'; const DriverQRCode = ({ driver }) => { // QR code data format expected by Traccar devices const qrData = JSON.stringify({ type: 'driver', uniqueId: driver.uniqueId }); return (

{driver.name}

Driver ID: {driver.uniqueId}

); }; // Handle driver identification from device // When device scans QR code, it sends driverUniqueId in position attributes socket.onmessage = (event) => { const data = JSON.parse(event.data); if (data.positions) { data.positions.forEach((position) => { if (position.attributes.driverUniqueId) { console.log(`Driver ${position.attributes.driverUniqueId} identified on device ${position.deviceId}`); // Log trip with driver association } }); } }; ``` -------------------------------- ### React Login and Registration Component Source: https://github.com/traccar/traccar-web/blob/master/simple/index.html Handles user login and new user registration. It makes POST requests to '/api/users' for registration and '/api/session' for login. It manages email and password input states and displays 'Register' or 'Login' button based on the server state. ```javascript const LoginScreen = ({ server, setServer, setUser }) => { const [email, setEmail] = React.useState(''); const [password, setPassword] = React.useState(''); const handleSubmit = (event) => { event.preventDefault(); const fetchData = async () => { if (server.newServer) { const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: email, email, password }), }); if (response.ok) { setServer({ ...server, newServer: false }); } } else { const query = `email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`; const response = await fetch('/api/session', { method: 'POST', body: new URLSearchParams(query), }); if (response.ok) { setUser(await response.json()); } } }; fetchData(); }; const formStyle = { width: '320px', margin: '32px', display: 'flex', flexDirection: 'column', }; return (
setEmail(e.target.value)} placeholder="Email" /> setPassword(e.target.value)} placeholder="Password" type="password" />
); }; ``` -------------------------------- ### Manage Traccar Users, Groups, and Permissions with JavaScript API Source: https://context7.com/traccar/traccar-web/llms.txt This snippet demonstrates how to use the Traccar API with JavaScript to create and manage users, establish hierarchical device groups, link devices to groups, and manage user permissions. It covers user creation, preference updates, device-to-user linking, group creation (root and sub-groups), device-to-group assignment, and retrieving user groups. ```javascript // Create new user const newUser = { name: 'Fleet Manager', email: 'manager@example.com', password: 'SecurePass123!', phone: '+1234567890', readonly: false, administrator: false, deviceLimit: 100, userLimit: 10, expirationTime: '2026-12-31T23:59:59Z', attributes: { timezone: 'America/New_York', speedUnit: 'kmh', distanceUnit: 'km', volumeUnit: 'liter' } }; const userResponse = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newUser) }); const createdUser = await userResponse.json(); // Update user preferences await fetch(`/api/users/${createdUser.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...createdUser, attributes: { ...createdUser.attributes, mapDefault: 'locationIqStreets', darkMode: true } }) }); // Link device to user await fetch('/api/permissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: createdUser.id, deviceId: 123 }) }); // Create hierarchical device group const rootGroup = { name: 'North America Fleet', attributes: { speedLimit: 110, fuelPrice: 1.5 } }; const rootResponse = await fetch('/api/groups', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(rootGroup) }); const root = await rootResponse.json(); // Create sub-group const subGroup = { name: 'Eastern Region', groupId: root.id, // Parent group attributes: { timezone: 'America/New_York' } }; const subResponse = await fetch('/api/groups', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(subGroup) }); const sub = await subResponse.json(); // Assign device to group await fetch(`/api/devices/123`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 123, groupId: sub.id, // ... other device properties }) }); // Link group to user await fetch('/api/permissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: createdUser.id, groupId: root.id }) }); // Get all groups for user const userGroupsResponse = await fetch(`/api/groups?userId=${createdUser.id}`); const userGroups = await userGroupsResponse.json(); ``` -------------------------------- ### User and Group Management API Source: https://context7.com/traccar/traccar-web/llms.txt Endpoints for managing users, roles, and hierarchical device groups. This includes creating, updating, linking users to devices and groups, and managing group structures. ```APIDOC ## POST /api/users ### Description Creates a new user in the system. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **name** (string) - Required - The name of the user. - **email** (string) - Required - The email address of the user. - **password** (string) - Required - The password for the user. - **phone** (string) - Optional - The phone number of the user. - **readonly** (boolean) - Optional - Whether the user is read-only. - **administrator** (boolean) - Optional - Whether the user is an administrator. - **deviceLimit** (integer) - Optional - The maximum number of devices the user can manage. - **userLimit** (integer) - Optional - The maximum number of users the user can create. - **expirationTime** (string) - Optional - The expiration date and time for the user account in ISO 8601 format. - **attributes** (object) - Optional - A key-value map of user attributes. - **timezone** (string) - Optional - The user's timezone. - **speedUnit** (string) - Optional - The preferred unit for speed. - **distanceUnit** (string) - Optional - The preferred unit for distance. - **volumeUnit** (string) - Optional - The preferred unit for volume. ### Request Example { "name": "Fleet Manager", "email": "manager@example.com", "password": "SecurePass123!", "phone": "+1234567890", "readonly": false, "administrator": false, "deviceLimit": 100, "userLimit": 10, "expirationTime": "2026-12-31T23:59:59Z", "attributes": { "timezone": "America/New_York", "speedUnit": "kmh", "distanceUnit": "km", "volumeUnit": "liter" } } ### Response #### Success Response (200) - **id** (integer) - The unique identifier of the created user. - **name** (string) - The name of the user. - **email** (string) - The email address of the user. - **phone** (string) - The phone number of the user. - **readonly** (boolean) - Whether the user is read-only. - **administrator** (boolean) - Whether the user is an administrator. - **deviceLimit** (integer) - The maximum number of devices the user can manage. - **userLimit** (integer) - The maximum number of users the user can create. - **expirationTime** (string) - The expiration date and time for the user account. - **attributes** (object) - A key-value map of user attributes. #### Response Example { "id": 1, "name": "Fleet Manager", "email": "manager@example.com", "phone": "+1234567890", "readonly": false, "administrator": false, "deviceLimit": 100, "userLimit": 10, "expirationTime": "2026-12-31T23:59:59Z", "attributes": { "timezone": "America/New_York", "speedUnit": "kmh", "distanceUnit": "km", "volumeUnit": "liter" } } ## PUT /api/users/{id} ### Description Updates an existing user's information and preferences. ### Method PUT ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the user to update. #### Request Body - **id** (integer) - Required - The unique identifier of the user. - **name** (string) - Optional - The updated name of the user. - **email** (string) - Optional - The updated email address of the user. - **password** (string) - Optional - The updated password for the user. - **phone** (string) - Optional - The updated phone number of the user. - **readonly** (boolean) - Optional - The updated read-only status. - **administrator** (boolean) - Optional - The updated administrator status. - **deviceLimit** (integer) - Optional - The updated device limit. - **userLimit** (integer) - Optional - The updated user limit. - **expirationTime** (string) - Optional - The updated expiration date and time. - **attributes** (object) - Optional - The updated user attributes. - **mapDefault** (string) - Optional - The default map layer. - **darkMode** (boolean) - Optional - Whether dark mode is enabled. ### Request Example { "id": 1, "name": "Fleet Manager", "email": "manager@example.com", "password": "SecurePass123!", "phone": "+1234567890", "readonly": false, "administrator": false, "deviceLimit": 100, "userLimit": 10, "expirationTime": "2026-12-31T23:59:59Z", "attributes": { "timezone": "America/New_York", "speedUnit": "kmh", "distanceUnit": "km", "volumeUnit": "liter", "mapDefault": "locationIqStreets", "darkMode": true } } ### Response #### Success Response (200) Returns the updated user object. #### Response Example { "id": 1, "name": "Fleet Manager", "email": "manager@example.com", "phone": "+1234567890", "readonly": false, "administrator": false, "deviceLimit": 100, "userLimit": 10, "expirationTime": "2026-12-31T23:59:59Z", "attributes": { "timezone": "America/New_York", "speedUnit": "kmh", "distanceUnit": "km", "volumeUnit": "liter", "mapDefault": "locationIqStreets", "darkMode": true } } ## POST /api/permissions ### Description Creates a permission link between a user and a device or a user and a group. ### Method POST ### Endpoint /api/permissions ### Parameters #### Request Body - **userId** (integer) - Required - The ID of the user. - **deviceId** (integer) - Optional - The ID of the device to link. - **groupId** (integer) - Optional - The ID of the group to link. ### Request Example { "userId": 1, "deviceId": 123 } ### Response #### Success Response (200) Indicates that the permission was successfully created. ### Response Example (No specific response body provided, typically an empty 200 OK or a success message) ## POST /api/groups ### Description Creates a new device group, which can be a root group or a sub-group. ### Method POST ### Endpoint /api/groups ### Parameters #### Request Body - **name** (string) - Required - The name of the group. - **groupId** (integer) - Optional - The ID of the parent group if creating a sub-group. - **attributes** (object) - Optional - A key-value map of group attributes. - **speedLimit** (integer) - Optional - The speed limit for the group. - **fuelPrice** (number) - Optional - The fuel price for the group. - **timezone** (string) - Optional - The timezone for the group. ### Request Example { "name": "North America Fleet", "attributes": { "speedLimit": 110, "fuelPrice": 1.5 } } ### Response #### Success Response (200) - **id** (integer) - The unique identifier of the created group. - **name** (string) - The name of the group. - **groupId** (integer) - The ID of the parent group, if applicable. - **attributes** (object) - A key-value map of group attributes. #### Response Example { "id": 1, "name": "North America Fleet", "groupId": null, "attributes": { "speedLimit": 110, "fuelPrice": 1.5 } } ## PUT /api/devices/{id} ### Description Updates an existing device's properties, including its group assignment. ### Method PUT ### Endpoint /api/devices/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the device to update. #### Request Body - **id** (integer) - Required - The unique identifier of the device. - **groupId** (integer) - Optional - The ID of the group to assign the device to. - ... other device properties can be included here ### Request Example { "id": 123, "groupId": 2 } ### Response #### Success Response (200) Indicates that the device was successfully updated. ### Response Example (No specific response body provided, typically an empty 200 OK or a success message) ## GET /api/groups?userId={userId} ### Description Retrieves all groups associated with a specific user. ### Method GET ### Endpoint /api/groups?userId={userId} ### Parameters #### Query Parameters - **userId** (integer) - Required - The ID of the user whose groups are to be retrieved. ### Response #### Success Response (200) - An array of group objects associated with the user. #### Response Example [ { "id": 1, "name": "North America Fleet", "groupId": null, "attributes": { "speedLimit": 110, "fuelPrice": 1.5 } }, { "id": 2, "name": "Eastern Region", "groupId": 1, "attributes": { "timezone": "America/New_York" } } ] ``` -------------------------------- ### Commands API Source: https://context7.com/traccar/traccar-web/llms.txt This API allows for retrieving command types, sending commands to devices, and managing saved commands. ```APIDOC ## GET /api/commands/types ### Description Retrieves a list of available command types that can be sent to a specific device. ### Method GET ### Endpoint /api/commands/types ### Parameters #### Query Parameters - **deviceId** (integer) - Required - The ID of the device for which to get command types. ### Response #### Success Response (200) An array of strings, where each string is a command type identifier. #### Response Example ```json ["positionPeriodic", "engineStop", "engineResume", "outputControl", "custom"] ``` ## POST /api/commands/send ### Description Sends a command to a specified device. ### Method POST ### Endpoint /api/commands/send ### Parameters #### Request Body - **deviceId** (integer) - Required - The ID of the target device. - **type** (string) - Required - The type of command to send (e.g., 'positionPeriodic', 'engineStop'). - **attributes** (object) - Optional - Additional attributes for the command (e.g., {"frequency": 30}). ### Request Example ```json { "deviceId": 123, "type": "positionPeriodic", "attributes": { "frequency": 30 } } ``` ### Response #### Success Response (200) Indicates the command was sent successfully. #### Error Response (4xx/5xx) Details about the failure to send the command. ## POST /api/commands ### Description Saves a command as a template for future use. ### Method POST ### Endpoint /api/commands ### Parameters #### Request Body - **description** (string) - Optional - A description for the saved command. - **type** (string) - Required - The type of command. - **attributes** (object) - Required - The attributes associated with the command. ### Request Example ```json { "description": "Request Position Every 30s", "type": "positionPeriodic", "attributes": { "frequency": 30 } } ``` ### Response #### Success Response (200) Returns the saved command object, including its assigned ID. #### Response Example ```json { "id": 5, "description": "Request Position Every 30s", "type": "positionPeriodic", "attributes": { "frequency": 30 } } ``` ## POST /api/permissions ### Description Links a saved command to a specific device, allowing the device to use the command template. ### Method POST ### Endpoint /api/permissions ### Parameters #### Request Body - **deviceId** (integer) - Required - The ID of the device. - **commandId** (integer) - Required - The ID of the saved command. ### Request Example ```json { "deviceId": 123, "commandId": 5 } ``` ### Response #### Success Response (200) Indicates the permission was granted successfully. ## GET /api/commands ### Description Retrieves a list of saved commands associated with a specific device. ### Method GET ### Endpoint /api/commands ### Parameters #### Query Parameters - **deviceId** (integer) - Optional - The ID of the device to filter commands by. ### Response #### Success Response (200) An array of saved command objects. #### Response Example ```json [ { "id": 5, "description": "Request Position Every 30s", "type": "positionPeriodic", "attributes": { "frequency": 30 } } ] ``` ``` -------------------------------- ### Redux State Management with Redux Toolkit (JavaScript) Source: https://context7.com/traccar/traccar-web/llms.txt Manages application state for devices, positions, and user session using Redux Toolkit. This includes defining reducers, configuring the store, and providing hooks for component interaction. It handles data fetching, WebSocket updates, and state selection. ```javascript import { configureStore, createSlice } from '@reduxjs/toolkit'; import { useSelector, useDispatch } from 'react-redux'; // Device slice const devicesSlice = createSlice({ name: 'devices', initialState: { items: {}, selectedId: null, selectTime: null }, reducers: { refresh: (state, action) => { state.items = {}; action.payload.forEach((device) => { state.items[device.id] = device; }); }, update: (state, action) => { action.payload.forEach((device) => { state.items[device.id] = device; }); }, selectId: (state, action) => { state.selectedId = action.payload; state.selectTime = Date.now(); }, remove: (state, action) => { delete state.items[action.payload]; if (state.selectedId === action.payload) { state.selectedId = null; } } } }); // Session slice const sessionSlice = createSlice({ name: 'session', initialState: { server: null, user: null, socket: false, positions: {}, history: {} }, reducers: { updateServer: (state, action) => { state.server = action.payload; }, updateUser: (state, action) => { state.user = action.payload; }, updateSocket: (state, action) => { state.socket = action.payload; }, updatePositions: (state, action) => { action.payload.forEach((position) => { state.positions[position.deviceId] = position; }); } } }); // Configure store const store = configureStore({ reducer: { devices: devicesSlice.reducer, session: sessionSlice.reducer } }); // Export actions export const { refresh, update, selectId, remove } = devicesSlice.actions; export const { updateServer, updateUser, updateSocket, updatePositions } = sessionSlice.actions; // Usage in components const DeviceList = () => { const dispatch = useDispatch(); const devices = useSelector((state) => Object.values(state.devices.items)); const selectedId = useSelector((state) => state.devices.selectedId); const positions = useSelector((state) => state.session.positions); // Load devices on mount useEffect(() => { const loadDevices = async () => { const response = await fetch('/api/devices'); const data = await response.json(); dispatch(refresh(data)); }; loadDevices(); }, [dispatch]); // Handle WebSocket updates useEffect(() => { const socket = new WebSocket('ws://localhost:8082/api/socket'); socket.onmessage = (event) => { const data = JSON.parse(event.data); if (data.devices) { dispatch(update(data.devices)); } if (data.positions) { dispatch(updatePositions(data.positions)); } }; return () => socket.close(); }, [dispatch]); return (
{devices.map((device) => { const position = positions[device.id]; return (
dispatch(selectId(device.id))} style={{ background: device.id === selectedId ? '#E3F2FD' : 'transparent' }} >

{device.name}

Status: {device.status}

{position && (

Speed: {(position.speed * 1.852).toFixed(1)} km/h

)}
); })}
); }; export default store; ``` -------------------------------- ### React Application Root Component Source: https://github.com/traccar/traccar-web/blob/master/simple/index.html The main App component orchestrates the application's state management for server configuration and user authentication. It fetches initial server and session data on mount. It conditionally renders either the MainScreen or LoginScreen based on user authentication status. ```javascript const App = () => { const [server, setServer] = React.useState(); const [user, setUser] = React.useState(); React.useEffect(() => { const fetchData = async () => { const serverResponse = await fetch('/api/server'); if (serverResponse.ok) { setServer(await serverResponse.json()); } const sessionResponse = await fetch('/api/session'); if (sessionResponse.ok) { setUser(await sessionResponse.json()); } } fetchData(); }, []); return user ? ( ) : server ? ( ) : ''; }; ReactDOM.render(, document.getElementById('content')); ``` -------------------------------- ### Configure Event Notifications via API (JavaScript) Source: https://context7.com/traccar/traccar-web/llms.txt This JavaScript code snippet demonstrates how to interact with the Traccar Web API to configure event-based notifications. It shows how to retrieve available event types and notification channels, create new notifications, link them to devices, test them, and send announcements. It utilizes `fetch` for API calls and assumes a JSON response structure. ```javascript await fetch('/api/notifications/types'); const eventTypes = await eventTypesResponse.json(); console.log('Event types:', eventTypes); await fetch('/api/notifications/notificators'); const notificators = await notificators.json(); console.log('Notification channels:', notificators); const notification = { type: 'deviceOverspeed', always: false, notificators: 'web,mail,firebase', attributes: { alarmEnabled: true } }; const notifResponse = await fetch('/api/notifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(notification) }); const createdNotification = await notifResponse.json(); await fetch('/api/permissions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ deviceId: 123, notificationId: createdNotification.id }) }); const geofenceNotification = { type: 'geofenceEnter', always: true, notificators: 'telegram,mail', attributes: {} }; await fetch('/api/notifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(geofenceNotification) }); const testResponse = await fetch('/api/notifications/test/mail', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ body: 'Test notification message' }) }); if (testResponse.ok) { console.log('Test notification sent successfully'); } await fetch('/api/notifications/send/web', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ subject: 'System Maintenance', body: 'Scheduled maintenance on Jan 15, 2025 from 2-4 AM' }) }); ``` -------------------------------- ### Notification Configuration API Source: https://context7.com/traccar/traccar-web/llms.txt Endpoints for managing notification types, channels, and configurations. ```APIDOC ## GET /api/notifications/types ### Description Retrieves a list of available event types for which notifications can be configured. ### Method GET ### Endpoint /api/notifications/types ### Parameters None ### Request Example None ### Response #### Success Response (200) - **eventTypes** (array) - A list of available notification event types. #### Response Example ```json [ "alarm", "ignitionOn", "ignitionOff", "geofenceEnter", "geofenceExit", "deviceMoving", "deviceStopped", "deviceOverspeed", "deviceFuelDrop" ] ``` ## GET /api/notifications/notificators ### Description Retrieves a list of available notification delivery channels. ### Method GET ### Endpoint /api/notifications/notificators ### Parameters None ### Request Example None ### Response #### Success Response (200) - **notificators** (array) - A list of available notification channels. #### Response Example ```json [ "web", "mail", "sms", "firebase", "telegram", "traccar", "command" ] ``` ## POST /api/notifications ### Description Creates a new notification configuration. ### Method POST ### Endpoint /api/notifications ### Parameters #### Request Body - **type** (string) - Required - The type of the event for the notification (e.g., 'deviceOverspeed', 'geofenceEnter'). - **always** (boolean) - Required - Specifies if the notification should be sent every time the event occurs. - **notificators** (string) - Required - A comma-separated string of notification channels to use. - **attributes** (object) - Optional - Additional attributes specific to the notification type. ### Request Example ```json { "type": "deviceOverspeed", "always": false, "notificators": "web,mail,firebase", "attributes": { "alarmEnabled": true } } ``` ### Response #### Success Response (200) - **id** (integer) - The ID of the created notification. #### Response Example ```json { "id": 1 } ``` ## POST /api/permissions ### Description Links a notification to a specific device. ### Method POST ### Endpoint /api/permissions ### Parameters #### Request Body - **deviceId** (integer) - Required - The ID of the device to link the notification to. - **notificationId** (integer) - Required - The ID of the notification to link. ### Request Example ```json { "deviceId": 123, "notificationId": 1 } ``` ### Response (No specific success response body detailed, assume 200 OK on success) ## POST /api/notifications/test/{notificator} ### Description Tests sending a notification through a specific channel without saving the configuration. ### Method POST ### Endpoint /api/notifications/test/{notificator} - **notificator** (string) - Path Parameter - The notification channel to test (e.g., 'mail'). ### Parameters #### Request Body - **body** (string) - Required - The content of the test notification message. ### Request Example ```json { "body": "Test notification message" } ``` ### Response #### Success Response (200) Indicates the test notification was sent successfully. #### Response Example (No specific response body detailed, check for 200 OK status) ## POST /api/notifications/send/{notificator} ### Description Sends an announcement to all users via a specified notification channel. ### Method POST ### Endpoint /api/notifications/send/{notificator} - **notificator** (string) - Path Parameter - The notification channel to use for sending the announcement (e.g., 'web'). ### Parameters #### Request Body - **subject** (string) - Required - The subject of the announcement. - **body** (string) - Required - The main content of the announcement. ### Request Example ```json { "subject": "System Maintenance", "body": "Scheduled maintenance on Jan 15, 2025 from 2-4 AM" } ``` ### Response (No specific success response body detailed, assume 200 OK on success) ``` -------------------------------- ### Session Authentication API - Traccar Web Source: https://context7.com/traccar/traccar-web/llms.txt Provides functions to log in, retrieve the current session, and log out of the Traccar platform. Uses the fetch API for HTTP requests. Handles authentication credentials and session management. ```javascript const response = await fetch('/api/session', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'user@example.com', password: 'securepassword123', token: '123456' // Optional: TOTP 2FA code }) }); if (response.ok) { const user = await response.json(); console.log('Logged in:', user); } // Get current session const sessionResponse = await fetch('/api/session'); if (sessionResponse.ok) { const currentUser = await sessionResponse.json(); } else { // Not authenticated - redirect to login window.location.href = '/login'; } // Logout await fetch('/api/session', { method: 'DELETE' }); ```