Watcher import fails with json/geojson created by Owntracks Recorder
First of all: Thanks for this great piece of software!
OS & Hardware Debian 12.11 amd64
Version 0.26.3
Describe the bug
OwnTracks Recorder comes with a CLI that allows to export data to several formats (see here). The standard is JSON. It can be created via e.g. (to export the default last 6 hours) docker exec otrecorder ocat -u user -d device >> /path/to/dawarich/watched/export.json (if OwnTracks Recorder runs in a Docker container). I tried to export this directly to my Dawarich's watched folder, but the import fails:
Import "owntracks-2025-05-19_test.json" failed: undefined method 'flatten' for nil, stacktrace: /var/app/app/services/geojson/params.rb:14:in 'Geojson::Params#call' /var/app/app/services/geojson/importer.rb:18:in 'Geojson::Importer#call' /var/app/app/services/imports/create.rb:12:in 'Imports::Create#call' /var/app/app/models/import.rb:18:in 'Import#process!' /var/app/app/jobs/import/process_job.rb:9:in 'Import::ProcessJob#perform' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:68:in 'block in ActiveJob::Execution#_perform_job' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:120:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n.rb:353:in 'I18n::Base#with_locale' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/translation.rb:9:in 'block (2 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'BasicObject#instance_exec' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/zones.rb:65:in 'Time.use_zone' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/timezones.rb:9:in 'block (2 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'BasicObject#instance_exec' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:140:in 'ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:67:in 'ActiveJob::Execution#_perform_job' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:32:in 'ActiveJob::Instrumentation#_perform_job' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:51:in 'ActiveJob::Execution#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:26:in 'block in ActiveJob::Instrumentation#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/railties/job_runtime.rb:13:in 'block in ActiveRecord::Railties::JobRuntime#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:40:in 'block in ActiveJob::Instrumentation#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb:210:in 'block in ActiveSupport::Notifications.instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb:210:in 'ActiveSupport::Notifications.instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:39:in 'ActiveJob::Instrumentation#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/railties/job_runtime.rb:11:in 'ActiveRecord::Railties::JobRuntime#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:26:in 'ActiveJob::Instrumentation#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/logging.rb:32:in 'block in ActiveJob::Logging#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/logging.rb:41:in 'ActiveJob::Logging#tag_logger' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/logging.rb:32:in 'ActiveJob::Logging#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/sentry-rails-5.23.0/lib/sentry/rails/active_job.rb:8:in 'Sentry::Rails::ActiveJobExtensions#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:29:in 'block in ActiveJob::Execution::ClassMethods#execute' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:120:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/railtie.rb:95:in 'block (4 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:77:in 'block in ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/execution_wrapper.rb:87:in 'ActiveSupport::ExecutionWrapper.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:74:in 'ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/railtie.rb:94:in 'block (3 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'BasicObject#instance_exec' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:140:in 'ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:27:in 'ActiveJob::Execution::ClassMethods#execute' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/rails.rb:13:in 'Sidekiq::ActiveJob::Wrapper#perform' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in 'Sidekiq::Processor#execute_job' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in 'block (4 levels) in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in 'Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in 'Sidekiq::Job::InterruptHandler#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in 'Sidekiq::Metrics::ExecutionTracker#track' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in 'Sidekiq::Metrics::Middleware#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in 'Sidekiq::Middleware::Chain#invoke' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in 'block (3 levels) in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in 'block (6 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in 'Sidekiq::JobRetry#local' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in 'block (5 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/rails.rb:27:in 'block in Sidekiq::Rails::Reloader#call' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:77:in 'block in ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/execution_wrapper.rb:91:in 'ActiveSupport::ExecutionWrapper.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:74:in 'ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/rails.rb:26:in 'Sidekiq::Rails::Reloader#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in 'block (4 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in 'Sidekiq::Processor#stats' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in 'block (3 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in 'Sidekiq::JobLogger#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in 'block (2 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in 'Sidekiq::JobRetry#global' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in 'block in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in 'Sidekiq::JobLogger#prepare' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in 'Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in 'block (2 levels) in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in 'Thread.handle_interrupt' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in 'block in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in 'Thread.handle_interrupt' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in 'Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in 'Sidekiq::Processor#process_one' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in 'Sidekiq::Processor#run' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in 'Sidekiq::Component#watchdog' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in 'block in Sidekiq::Component#safe_thread'
Manually importing it fails as well.
OwnTracks' ocat CLI supports several other formats and as I found out the Dawarich watcher only supports GeoJSON and GPX, so I tried to export it as GeoJSON:
docker exec otrecorder ocat -u user -d device --format geojson >> /path/to/dawarich/watched/export.json
This fails as well, also when imported manually:
Import "owntracks-geojson-test.json" failed: Validation failed: Timestamp can't be blank, stacktrace: /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/validations.rb:87:in 'ActiveRecord::Validations#raise_validation_error' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/validations.rb:54:in 'ActiveRecord::Validations#save!' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/transactions.rb:365:in 'block in ActiveRecord::Transactions#save!' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/transactions.rb:417:in 'block (2 levels) in ActiveRecord::Transactions#with_transaction_returning_status' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/connection_adapters/abstract/transaction.rb:626:in 'block in ActiveRecord::ConnectionAdapters::TransactionManager#within_new_transaction' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/null_lock.rb:9:in 'ActiveSupport::Concurrency::NullLock#synchronize' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/connection_adapters/abstract/transaction.rb:623:in 'ActiveRecord::ConnectionAdapters::TransactionManager#within_new_transaction' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:367:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#within_new_transaction' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:359:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/transactions.rb:413:in 'block in ActiveRecord::Transactions#with_transaction_returning_status' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:418:in 'ActiveRecord::ConnectionAdapters::ConnectionPool#with_connection' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/connection_handling.rb:310:in 'ActiveRecord::ConnectionHandling#with_connection' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/transactions.rb:409:in 'ActiveRecord::Transactions#with_transaction_returning_status' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/transactions.rb:365:in 'ActiveRecord::Transactions#save!' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/suppressor.rb:56:in 'ActiveRecord::Suppressor#save!' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/persistence.rb:55:in 'ActiveRecord::Persistence::ClassMethods#create!' /var/app/app/services/geojson/importer.rb:24:in 'block in Geojson::Importer#call' /var/app/app/services/geojson/importer.rb:20:in 'Array#each' /var/app/app/services/geojson/importer.rb:20:in 'Enumerator#with_index' /var/app/app/services/geojson/importer.rb:20:in 'Geojson::Importer#call' /var/app/app/services/imports/create.rb:12:in 'Imports::Create#call' /var/app/app/models/import.rb:18:in 'Import#process!' /var/app/app/jobs/import/process_job.rb:9:in 'Import::ProcessJob#perform' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:68:in 'block in ActiveJob::Execution#_perform_job' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:120:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n.rb:353:in 'I18n::Base#with_locale' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/translation.rb:9:in 'block (2 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'BasicObject#instance_exec' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/zones.rb:65:in 'Time.use_zone' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/timezones.rb:9:in 'block (2 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'BasicObject#instance_exec' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:140:in 'ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:67:in 'ActiveJob::Execution#_perform_job' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:32:in 'ActiveJob::Instrumentation#_perform_job' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:51:in 'ActiveJob::Execution#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:26:in 'block in ActiveJob::Instrumentation#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/railties/job_runtime.rb:13:in 'block in ActiveRecord::Railties::JobRuntime#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:40:in 'block in ActiveJob::Instrumentation#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb:210:in 'block in ActiveSupport::Notifications.instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/instrumenter.rb:58:in 'ActiveSupport::Notifications::Instrumenter#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb:210:in 'ActiveSupport::Notifications.instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:39:in 'ActiveJob::Instrumentation#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activerecord-8.0.2/lib/active_record/railties/job_runtime.rb:11:in 'ActiveRecord::Railties::JobRuntime#instrument' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/instrumentation.rb:26:in 'ActiveJob::Instrumentation#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/logging.rb:32:in 'block in ActiveJob::Logging#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/logging.rb:41:in 'ActiveJob::Logging#tag_logger' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/logging.rb:32:in 'ActiveJob::Logging#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/sentry-rails-5.23.0/lib/sentry/rails/active_job.rb:8:in 'Sentry::Rails::ActiveJobExtensions#perform_now' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:29:in 'block in ActiveJob::Execution::ClassMethods#execute' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:120:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/railtie.rb:95:in 'block (4 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:77:in 'block in ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/execution_wrapper.rb:87:in 'ActiveSupport::ExecutionWrapper.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:74:in 'ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/railtie.rb:94:in 'block (3 levels) in ' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'BasicObject#instance_exec' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:129:in 'block in ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb:140:in 'ActiveSupport::Callbacks#run_callbacks' /var/app/vendor/bundle/ruby/3.4.0/gems/activejob-8.0.2/lib/active_job/execution.rb:27:in 'ActiveJob::Execution::ClassMethods#execute' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/rails.rb:13:in 'Sidekiq::ActiveJob::Wrapper#perform' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in 'Sidekiq::Processor#execute_job' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in 'block (4 levels) in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in 'Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in 'Sidekiq::Job::InterruptHandler#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in 'block in Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in 'Sidekiq::Metrics::ExecutionTracker#track' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in 'Sidekiq::Metrics::Middleware#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in 'Sidekiq::Middleware::Chain#traverse' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in 'Sidekiq::Middleware::Chain#invoke' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in 'block (3 levels) in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in 'block (6 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in 'Sidekiq::JobRetry#local' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in 'block (5 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/rails.rb:27:in 'block in Sidekiq::Rails::Reloader#call' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:77:in 'block in ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/execution_wrapper.rb:91:in 'ActiveSupport::ExecutionWrapper.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb:74:in 'ActiveSupport::Reloader.wrap' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/rails.rb:26:in 'Sidekiq::Rails::Reloader#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in 'block (4 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in 'Sidekiq::Processor#stats' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in 'block (3 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in 'Sidekiq::JobLogger#call' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in 'block (2 levels) in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in 'Sidekiq::JobRetry#global' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in 'block in Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in 'Sidekiq::JobLogger#prepare' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in 'Sidekiq::Processor#dispatch' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in 'block (2 levels) in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in 'Thread.handle_interrupt' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in 'block in Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in 'Thread.handle_interrupt' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in 'Sidekiq::Processor#process' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in 'Sidekiq::Processor#process_one' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in 'Sidekiq::Processor#run' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in 'Sidekiq::Component#watchdog' /var/app/vendor/bundle/ruby/3.4.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in 'block in Sidekiq::Component#safe_thread'
To Reproduce Steps to reproduce the behavior:
- Create a GeoJSON file with OwnTracks Recorder.
- Try to import that file to Dawarich either with the Watcher or with the web interface.
Expected behavior Successful import of these files.
Additional context
The documentation on importing from OwnTracks still mentions the JSON created by OwnTracks, but apparently the support for these JSONs was replaced by support for REC-files. So I created a REC file with ocat, using their 'raw' format as mentioned in their documentation: docker exec otrecorder ocat -u user -d device --format raw >> export.rec
Uploading this file in the web interface works, same with a GPX file created by ocat.
~~Unfortunately the Watcher doesn't support importing the REC files and~~ GPX files don't seem to contain all the data.
A very good and simple solution would probably be to remove every mention of JSON from the documentation on importing from OwnTracks and making clear that OwnTracks' JSON files are not supported ~~and to add support for REC files to the Watcher (if that can easily be done. This would allow to e.g. run OwnTracks Recorder and Dawarich in parallel and automatically exporting from the Recorder to Dawarich's Watcher with a Cron job.).~~
Thanks for taking this into consideration.
Edit: Update: I found out, that the Watcher supports importing .rec files. It's just not mentioned in the documentation. So I propose this info to be added and the mention of JSON to be replaced with .rec in the guide on how to import data from OwnTracks to Dawarich (I can do that and also describe how to export a .rec file via CLI – see my comment below).
I don't think your converter creates a valid geojson file, at least valid to Dawarich. I can debug it if you sent the file to [email protected]. You can also don't convert your owntracks file (assuming it's a .rec one) and Dawarich should consume it with no problems
I don't think your converter creates a valid geojson file, at least valid to Dawarich. I can debug it if you sent the file to [email protected]. You can also don't convert your owntracks file (assuming it's a .rec one) and Dawarich should consume it with no problems
Hi, thanks for your answer. It's not a converter but the CLI that comes with OwnTracks and the recommended way to export data from OwnTracks since they removed the download button from the web interface. That being said: It supports various formats and exporting a .rec file and importing it in the web interface works without problems, ~~but the Watcher can't import .rec files afaik (see my last paragraph above).~~
~~If the Watcher could be upgraded to be able to consume .rec files, this would solve all issues.~~
I still also recommend removing the mention of JSON from the documentation on importing data from OwnTracks to Dawarich. I can do that and add a paragraph on how to export rec files with OwnTracks' CLI and import them to Dawarich instead, if you want.
~~I believe adding .rec support to the watcher and updating the documentation on importing from OwnTracks solves this well, but~~ here are examples of the JSON and GeoJSON files generated by OwnTracks (I removed the coordinates and some personal information): GeoJSON:
{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[0.0,0.0]},"properties":{"name":"DK","vel":0,"tst":1747785355,"acc":5,"alt":30,"address":"","isotst":"2025-05-20T23:55:55Z"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[0.0,0.0]},"properties":{"name":"DK","vel":0,"tst":1747785358,"acc":14,"alt":31,"address":"","isotst":"2025-05-20T23:55:58Z"}}]}
JSON:
{"count":2,"locations":[{"tid":"DK","batt":10,"lon":0.0,"acc":5,"bs":1,"inrids":[],"vel":0,"vac":5,"inregions":[],"lat":0.0,"topic":"owntracks/user/device","bssid":"removed","conn":"w","tst":1747785355,"m":1,"ssid":"WLAN-SSID","alt":30,"_type":"location","_http":true,"ghash":"u1x09zp","isorcv":"2025-05-20T23:55:55Z","isotst":"2025-05-20T23:55:55Z","disptst":"2025-05-20 23:55:55"},{"bs":1,"p":100.906,"batt":10,"tid":"DK","_type":"location","topic":"owntracks/user/device","alt":31,"ssid":"WLAN-SSID","lon":0.0,"vel":0,"bssid":"removed","t":"u","conn":"w","vac":16,"acc":14,"tst":1747785358,"lat":0.0,"m":1,"inrids":[],"inregions":[],"_http":true,"ghash":"u1x09zp","isorcv":"2025-05-20T23:55:58Z","isotst":"2025-05-20T23:55:58Z","disptst":"2025-05-20 23:55:58"}]}
Edit: I found out, the Watcher supports .rec files, see below.
You can also don't convert your owntracks file (assuming it's a .rec one) and Dawarich should consume it with no problems
I just tried and found out that the Watcher can consume .rec files, so I propose a simple solution that requires almost no work on your part: Adding that information to the Watcher's documentation, removing any mention of JSON in the documentation on importing data from OwnTracks to Dawarich and instead describing how to get .rec files from OwnTracks and import them to Dawarich. I can write those changes to the documentation, if you want.
Docs are updated, thank you