diff --git a/src/config-manager.js b/src/config-manager.js
index 92ff44f..74b6aef 100644
--- a/src/config-manager.js
+++ b/src/config-manager.js
@@ -11,13 +11,23 @@ export class ConfigManager {
/**
* Validates and sets the configuration
* @param {Object} config - User configuration
- * @throws {Error} If entities are not defined
+ * @throws {Error} If entities are not defined or invalid configuration values
*/
setConfig(config) {
if (!config.entities || !Array.isArray(config.entities)) {
throw new Error('You need to define entities');
}
+ // Validate speed_source configuration
+ if (config.speed_source && !['calculated', 'sensor'].includes(config.speed_source)) {
+ throw new Error(`Invalid speed_source "${config.speed_source}". Must be either 'calculated' or 'sensor'.`);
+ }
+
+ // Validate activity_source configuration
+ if (config.activity_source && !['sensor', 'speed_predicted'].includes(config.activity_source)) {
+ throw new Error(`Invalid activity_source "${config.activity_source}". Must be either 'sensor' or 'speed_predicted'.`);
+ }
+
const mergedActivities = this._mergeActivities(config.activities);
this._config = {
@@ -32,6 +42,7 @@ export class ConfigManager {
marker_size: config.marker_size || DEFAULT_CONFIG.marker_size,
use_predicted_activity: config.use_predicted_activity || DEFAULT_CONFIG.use_predicted_activity,
activity_source: config.activity_source || DEFAULT_CONFIG.activity_source,
+ speed_source: config.speed_source || DEFAULT_CONFIG.speed_source,
zones: config.zones || DEFAULT_CONFIG.zones,
activities: mergedActivities,
debug: config.debug || DEFAULT_CONFIG.debug
@@ -98,12 +109,21 @@ export class ConfigManager {
maptype: this._config.map_type,
zoom: this._config.default_zoom,
mode: 'proxy',
+ activity_source: this._config.activity_source,
+ speed_source: this._config.speed_source,
debug: this._config.debug ? '1' : '0'
});
// Add entities
const entitiesParam = this._config.entities
- .map(e => `${e.person}${e.activity ? ':' + e.activity : ''}`)
+ .map(e => {
+ let entityStr = e.person;
+ const params = [];
+ if (e.activity) params.push(`activity=${e.activity}`);
+ if (e.speed) params.push(`speed=${e.speed}`);
+ if (params.length > 0) entityStr += ':' + params.join(',');
+ return entityStr;
+ })
.join(',');
params.append('entities', entitiesParam);
diff --git a/src/constants.js b/src/constants.js
index 7a9cad4..2f7aa19 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -49,6 +49,14 @@ export const ACTIVITY_THRESHOLDS = {
vehicle: 7
};
+/**
+ * Speed source options for configuration
+ */
+export const SPEED_SOURCE_OPTIONS = {
+ calculated: 'Calculated from location updates',
+ sensor: 'Direct from speed sensor'
+};
+
/**
* Default zone configurations
*/
@@ -72,6 +80,7 @@ export const DEFAULT_CONFIG = {
marker_size: 'medium',
use_predicted_activity: false,
activity_source: 'sensor',
+ speed_source: 'calculated', // 'calculated' or 'sensor' - maintains backward compatibility
debug: false,
zones: DEFAULT_ZONES,
activities: {}
diff --git a/src/editor-handlers.js b/src/editor-handlers.js
index 01d1d36..f3c9eb3 100644
--- a/src/editor-handlers.js
+++ b/src/editor-handlers.js
@@ -15,6 +15,7 @@ export class EditorHandlers {
this._attachBorderRadiusListeners(element, config, onChange);
this._attachMarkerSizeListener(element, config, onChange);
this._attachActivitySourceListener(element, config, onChange);
+ this._attachSpeedSourceListener(element, config, onChange);
this._attachEntityListeners(element, config, onChange, onRender);
this._attachZoneListeners(element, config, onChange, onRender);
this._attachActivityListeners(element, config, onChange);
@@ -46,6 +47,19 @@ export class EditorHandlers {
});
}
+ /**
+ * Attaches speed source listener
+ * @param {HTMLElement} element - Root element
+ * @param {Object} config - Configuration object
+ * @param {Function} onChange - Callback when config changes
+ */
+ static _attachSpeedSourceListener(element, config, onChange) {
+ element.querySelector('#speed_source')?.addEventListener('selected', (e) => {
+ config.speed_source = e.target.value;
+ onChange();
+ });
+ }
+
/**
* Attaches map provider listeners
* @param {HTMLElement} element - Root element
@@ -178,7 +192,7 @@ export class EditorHandlers {
// Add entity button
element.querySelector('#add-entity')?.addEventListener('click', () => {
- config.entities.push({ person: '', activity: '' });
+ config.entities.push({ person: '', activity: '', speed: '' });
onRender();
onChange();
});
diff --git a/src/editor-ui.js b/src/editor-ui.js
index 1859e06..442421c 100644
--- a/src/editor-ui.js
+++ b/src/editor-ui.js
@@ -378,6 +378,21 @@ export class EditorUI {
- In Vehicle: > 7 km/h
+
+
+
+ Calculated from GPS
+ Speed Sensor
+
+
+ Choose how speed is determined.
+ 'Calculated from GPS' computes speed from location updates.
+ 'Speed Sensor' uses a dedicated Home Assistant speed sensor.
+