From 06406591d04deded73742505894bbee1a53c4d2c Mon Sep 17 00:00:00 2001 From: Andrei Sokolov Date: Sun, 9 Nov 2025 15:25:48 +0100 Subject: [PATCH 1/2] Return family tracking data to OwnTrack app --- .../api/v1/owntracks/points_controller.rb | 4 +- .../own_tracks/family_locations_formatter.rb | 52 +++++++++++++++++++ app/services/own_tracks/params.rb | 52 +++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 app/services/own_tracks/family_locations_formatter.rb diff --git a/app/controllers/api/v1/owntracks/points_controller.rb b/app/controllers/api/v1/owntracks/points_controller.rb index 6f97cfe9..9dc8cbe9 100644 --- a/app/controllers/api/v1/owntracks/points_controller.rb +++ b/app/controllers/api/v1/owntracks/points_controller.rb @@ -7,7 +7,9 @@ class Api::V1::Owntracks::PointsController < ApiController def create Owntracks::PointCreatingJob.perform_later(point_params, current_api_user.id) - render json: {}, status: :ok + family_locations = OwnTracks::FamilyLocationsFormatter.new(current_api_user).call + + render json: family_locations, status: :ok end private diff --git a/app/services/own_tracks/family_locations_formatter.rb b/app/services/own_tracks/family_locations_formatter.rb new file mode 100644 index 00000000..203bfa03 --- /dev/null +++ b/app/services/own_tracks/family_locations_formatter.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class OwnTracks::FamilyLocationsFormatter + attr_reader :user + + def initialize(user) + @user = user + end + + def call + return [] unless family_feature_enabled? + return [] unless user.in_family? + + sharing_members = family_members_with_sharing_enabled + return [] unless sharing_members.any? + + latest_points = sharing_members.map { |member| member.points.order(timestamp: :desc).first }.compact + latest_points.map { |point| build_owntracks_location(point) }.compact + end + + private + + def family_feature_enabled? + DawarichSettings.family_feature_enabled? + end + + def family_members_with_sharing_enabled + user.family.members + .where.not(id: user.id) + .select(&:family_sharing_enabled?) + end + + def build_owntracks_location(point) + location = { + _type: 'location', + lat: point.lat.to_f, + lon: point.lon.to_f, + tst: point.timestamp.to_i, + tid: point.user.email, + acc: point.accuracy, + alt: point.altitude, + batt: point.battery, + bs: OwnTracks::Params.battery_status_to_numeric(point.battery_status), + # t: OwnTracks::Params.trigger_to_string(point.trigger), + vel: OwnTracks::Params.velocity_to_kmh(point.velocity), + conn: OwnTracks::Params.connection_to_string(point.connection), + } + + location + end +end + diff --git a/app/services/own_tracks/params.rb b/app/services/own_tracks/params.rb index 838af33a..0306f455 100644 --- a/app/services/own_tracks/params.rb +++ b/app/services/own_tracks/params.rb @@ -90,4 +90,56 @@ class OwnTracks::Params def valid_point? params[:lon].present? && params[:lat].present? && params[:tst].present? end + + # Reverse conversion methods: from internal format to Owntracks format + class << self + def battery_status_to_numeric(battery_status) + case battery_status + when 'unknown' then 0 + when 'unplugged' then 1 + when 'charging' then 2 + when 'full' then 3 + else 0 + end + end + + def trigger_to_string(trigger) + case trigger + when 'background_event' then 'p' + when 'circular_region_event' then 'c' + when 'beacon_event' then 'b' + when 'report_location_message_event' then 'r' + when 'manual_event' then 'u' + when 'timer_based_event' then 't' + when 'settings_monitoring_event' then 'v' + else nil + end + end + + def connection_to_string(connection) + case connection + when 'mobile' then 'm' + when 'wifi' then 'w' + when 'offline' then 'o' + else nil + end + end + + def velocity_to_kmh(velocity) + return nil if velocity.blank? + + # Try to parse as float + velocity_float = velocity.to_f + return nil if velocity_float.zero? + + # Velocity should be in km/h for Owntracks format (integer) + # If stored as m/s (typically < 50), convert to km/h + # Otherwise assume it's already in km/h + if velocity_float < 50 + (velocity_float * 3.6).round.to_i + else + velocity_float.round.to_i + end + end + end end From c181a2f9a20d450ec7ff8e762faa732186a0ac7f Mon Sep 17 00:00:00 2001 From: Andrei Sokolov Date: Sun, 23 Nov 2025 12:41:50 +0100 Subject: [PATCH 2/2] clean up --- .../own_tracks/family_locations_formatter.rb | 1 - app/services/own_tracks/params.rb | 23 ++----------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/app/services/own_tracks/family_locations_formatter.rb b/app/services/own_tracks/family_locations_formatter.rb index 203bfa03..f25aa955 100644 --- a/app/services/own_tracks/family_locations_formatter.rb +++ b/app/services/own_tracks/family_locations_formatter.rb @@ -41,7 +41,6 @@ class OwnTracks::FamilyLocationsFormatter alt: point.altitude, batt: point.battery, bs: OwnTracks::Params.battery_status_to_numeric(point.battery_status), - # t: OwnTracks::Params.trigger_to_string(point.trigger), vel: OwnTracks::Params.velocity_to_kmh(point.velocity), conn: OwnTracks::Params.connection_to_string(point.connection), } diff --git a/app/services/own_tracks/params.rb b/app/services/own_tracks/params.rb index 0306f455..7f5c2d1f 100644 --- a/app/services/own_tracks/params.rb +++ b/app/services/own_tracks/params.rb @@ -103,19 +103,6 @@ class OwnTracks::Params end end - def trigger_to_string(trigger) - case trigger - when 'background_event' then 'p' - when 'circular_region_event' then 'c' - when 'beacon_event' then 'b' - when 'report_location_message_event' then 'r' - when 'manual_event' then 'u' - when 'timer_based_event' then 't' - when 'settings_monitoring_event' then 'v' - else nil - end - end - def connection_to_string(connection) case connection when 'mobile' then 'm' @@ -132,14 +119,8 @@ class OwnTracks::Params velocity_float = velocity.to_f return nil if velocity_float.zero? - # Velocity should be in km/h for Owntracks format (integer) - # If stored as m/s (typically < 50), convert to km/h - # Otherwise assume it's already in km/h - if velocity_float < 50 - (velocity_float * 3.6).round.to_i - else - velocity_float.round.to_i - end + # Reference: https://owntracks.org/booklet/tech/json/ + (velocity_float * 3.6).round.to_i end end end