Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Device location

atcd can send the position of a device to atc-server, which shows it on the console map. atcd does not read GPS hardware. A process of yours sends the position to atcd with the command atcd attr set-location.

Only an enrolled device that pulls from atc-server sends a position.

Send a position with atcd attr set-location

atcd attr set-location sends one position to the running atcd over the control socket, as atcd attr set does. atcd checks the position and applies the location.* send rules. A queued position goes out in the next report and shows on the console map. A throttled position waits until the interval ends. atcd does not send a too_close or an unchanged position. See Outcomes and exit codes.

atcd attr set-location --lat 39.7392 --lon -104.9903 --accuracy-m 8
OptionRequiredMeaning
--latyesLatitude in degrees, from -90 to 90.
--lonyesLongitude in degrees, from -180 to 180.
--accuracy-mnoThe accuracy estimate in metres, 0 or more.
--timestampnoWhen the position was measured, RFC 3339. If it is absent, atcd uses the time it read the request.
--socketnoThe control socket. The default is /run/atcd/atcd.sock.

Add the global option --json for a JSON answer: {"outcome": "queued"}.

One call for each location.min_interval_secs is enough. Inside the interval, atcd holds the newest position. When the interval ends, atcd sends it if it moved far enough. A more frequent call replaces the held position. Each call is one process start and one connection.

Who can run it

The command needs access to the control socket. The socket has mode 0660. On a non-root atcd, root and the members of the group of the daemon user have access. Use the least privilege that works:

  • Run the sender as root or as the daemon user (atc by default).
  • Or give the GPS user one sudo rule. It lets that user run only this subcommand as the daemon user:
<gps-user> ALL=(<daemon user>) NOPASSWD: /usr/local/bin/atcd attr set-location *

The path is daemon.remote_path, /usr/local/bin/atcd by default. On a root atcd, bootstrap gives the control socket to the SSH login user of the install, with the group root. So on a root atcd the sudo rule names root, or the sender runs as that login user.

Adding the GPS user to the group of the daemon user also gives access. It gives much more.

A member of that group can run every operation that the control mode allows. On a direct_allowed device, this includes pushes, activations and recovery. On a server_only device, it includes diagnostics, atcd attr and atcd attr set-location. The group is also the group of the store. Under hook isolation, the install gives the group %<group> ALL=(<hook user>) NOPASSWD: ALL. So a member can run any command as the hook user, whatever the control mode.

Do not use the group for a sender that only needs to send a position.

Outcomes and exit codes

On success the command prints position sent to atcd: <meaning>:

OutcomeMeaning
queuedqueued, goes out with the next report
throttledheld until location.min_interval_secs has passed since the last send, then checked against location.min_distance_m again
too_closenot sent, closer than location.min_distance_m to the last send
unchangednot sent, the same as the last send
Exit codeMeaning
0atcd took the position. Any outcome gives 0.
4atcd refused it. Causes: a bad position, for example atcd refused: lat must be from -90 to 90, got 95; location.enabled is false; this atcd runs no location reader because it does not pull from atc-server; or an atcd that has atcd attr but not this command, which answers “unknown attributes verb 4; update atcd”.
3Nothing accepts a connection on the socket.
5atcd accepted the connection and did not answer: a timeout or a hang-up.
1atcd could not run it, or the atcd is older than atcd attr. A fault means the location input of atcd is busy, gone or stopped, or did not answer in 10 s. In the last case atcd may still send the position.

After an upgrade

An earlier dev build read positions from a location socket, /run/atcd/location.sock, and from the command atcd location set. Both are gone. A connect to a leftover location.sock fails with “connection refused”. Move the sending process to atcd attr set-location.

The earlier build also left three things on a device. They grant and hold nothing now. Install and update never create or remove them. Uninstall removes the drop-in with the unit, and keeps the group and the folder:

  • the group atc-location;
  • the drop-in atc-location-group.conf in /etc/systemd/system/<service>.service.d/;
  • the folder /var/lib/atc-location.

In these paths and commands, <service> is the daemon.service_name of the device, atcd by default. An install by the socket release named the group in the main unit, /etc/systemd/system/<service>.service, on its SupplementaryGroups= line. Only an update of an older unit added the drop-in. A device can have either one.

atc bootstrap atcd update keeps the group and the drop-in. A unit that names the group fails to start without it, so do not delete the group alone. To remove the group, use this order:

  1. If the drop-in atc-location-group.conf is there, delete it.
  2. Take atc-location out of SupplementaryGroups= in the main unit.
  3. Run sudo systemctl daemon-reload.
  4. Run systemctl show -p SupplementaryGroups <service>. If the command fails, or its output still names atc-location, stop here. Find the file that names the group, fix it, and go back to step 3.
  5. Restart atcd: sudo systemctl restart <service>.
  6. Run sudo groupdel atc-location.

The folder can hold files of your own. To remove it, stop the process that wrote position.json. Delete position.json and position.json.tmp. Remove the folder only if it is empty.

Settings

Four device settings control what atcd sends. They are not in atc.toml.

SettingDefaultMeaning
location.enabledtrueSet it to false to stop the device from sending a position. atcd then refuses each position with a reason.
location.min_interval_secs60atcd sends a position at most once in this many seconds.
location.min_distance_m25atcd does not send a move shorter than this many metres.
location.precision_decimals5atcd rounds lat and lon to this many decimal places before it sends them. 5 is about 1 m, 3 is about 100 m. The maximum is 7.

atcd applies the rules in this order: it rounds the position, checks the interval, then checks the distance.

An enrolled device refuses atc ota settings set from a laptop, because it accepts changes only from the server. So set a value on the device, as the account that runs atcd (atc by default):

sudo -u atc atcd settings set location.min_interval_secs=300

atcd reads its settings only when it starts. Restart it to apply the value:

sudo systemctl restart atcd

An earlier release read the position from a file, set by location.file. atcd reads no file now, and skips a stored location.file row.

What the server does

atcd sends the position in the location section of its report. atc-server keeps only the latest position of each device. A position with an older timestamp than the stored one does not replace it.

When location.enabled is false, atcd stops sending new positions. The server keeps the last position it stored.

An organization can turn location off for all its devices. The server then deletes the stored positions, drops new ones, and hides the map. The device still sends its reports.

An atc-server older than this feature accepts the report and drops the position. It does not acknowledge the section. atcd then holds the position for one hour. In that hour it sends no new position to that server. After the hour it sends the newest position in one report, and holds again. The counter atcd.pull.location_unacked_total counts each such report.

Telemetry

atcd.location.read_total{outcome} counts each position once, by the outcome atcd answered: queued, throttled, too_close, unchanged, parse_error and disabled. It counts disabled once at start, and once for each position refused for it.

The map

The console map uses OpenStreetMap tiles. It shows the credit “© OpenStreetMap contributors”.