defmodule Microwaveprop.Radio.CallsignClient do @moduledoc "Looks up amateur radio callsign locations via gridmap.org." @doc """ Fetch location for a callsign. Returns {:ok, %{callsign, gridsquare, lat, lon}} or {:error, reason}. """ def locate(callsign) do url = "https://gridmap.org/locate/#{URI.encode(callsign)}" case Req.get(url, req_options() ++ [receive_timeout: 10_000]) do {:ok, %{status: 200, body: %{"latitude" => lat, "longitude" => lon} = body}} when is_number(lat) -> {:ok, %{ callsign: body["callsign"] || callsign, gridsquare: body["gridsquare"], lat: lat, lon: lon }} {:ok, %{status: 200, body: _}} -> {:error, "callsign not found"} {:ok, %{status: 404}} -> {:error, "callsign not found"} {:ok, %{status: status}} -> {:error, "gridmap.org HTTP #{status}"} {:error, reason} -> {:error, "gridmap.org failed: #{inspect(reason)}"} end end defp req_options do Application.get_env(:microwaveprop, :callsign_req_options, []) end end