Shutdown computer when sync is done

When a change happens in my folder I will trigger a wake up action (WoL or other way) to the remote device so that sync starts (ST yet setup as a service)

On remote side I think I’d use a cron hourly to run a script that detects sync is done then shutdown the pc.

I read doc and found rest/db/completion but they say its expensive. There is also /rest/events?events=FolderCompletion but it may happens that no change is needed in the folder since last startup… so if IUC the event will not rise.

What’s the best way please. Thanks

Hi @cosas,

in my opinion detecting “sync is done” can be achieved with much effort put into it. This is because you’d have to track events, cache completion stats (files, folders, symlinks, deletes) in memory and then update your cache if new events come in. It works this way when analyzing Syncthing’s Web UI js code (SyncthingController.js). I’ve studied it extensively to implement eventing and completion detection into Syncthing-Android.

I think some weeks ago(?) there was a ticket on this forum or GitHub asking for a separate API endpoint which provides a brief summary of overall sync progress for users who just like to know “is everything currently connected in sync or not”.

Implementing this to Syncthing-Android, I stumbled upon an interpretation problem. How do, for example, count paused or offline devices to the full sync completion? This can be determined very easy when looking at the Web UI, but programatically a decision has to be made.

Refs:

1 Like

I sometimes have the same use case therefore included this into syncthingctl, e.g.:

syncthingctl wait-for-idle --dir foo && systemctl poweroff

This tool is developed within the Syncthing Tray project. The --help for wait-for-idle looks like this:

wait-for-idle, -w
  waits until the specified dirs/devs are idling
  --dir, -d [ID]
    specifies a directory by ID
  --dev [ID/name]
    specifies a device by ID or name
  --all-dirs
    applies the operation for all directories
  --all-devs
    applies the operation for all devices
  --at-least, -a [number]
    specifies for how many milliseconds Syncthing must idle (prevents exiting too early in case of flaky status)
  --timeout, -t [number]
    specifies how many milliseconds to wait at most

  example: syncthingctl wait-for-idle --timeout 1800000 --at-least 5000 && systemctl poweroff
           syncthingctl wait-for-idle --dir dir1 --dir dir2 --dev dev1 --dev dev2 --at-least 5000

Within this tool I use the regular REST API routes to query the initial state and the event API to be notified about changes. So the “expensive” routes are only used initially/once. I think that answers your question regarding the API usage.

syncthingctl is only about local completion (of course one can simply connect to a remote instance with the --url parameter). But for the UI I also implemented notifications for remote folders. When I remember correctly, I’ve used the db/completion route to query the remove completion and the RemoteIndexUpdated event to know when it might have changed and needs to be queries again.

4 Likes

Many thanks guys. I’ll test this stuff, I think it will be easy for me as the folder in remote device I want to shutdown is “Receive only” and will never be paused.

rest/db/completion was wrong as it always returns "completion": 0, against our device + folder whatever Up to Date or Syncing.

Instead rest/db/need does the job for me :slight_smile: :

curl -k -X GET -H "X-API-Key: myAPIkey" 'https://localhost:8384/rest/db/need?folder=myFol-derID'
{
 "page": 1,
 "perpage": 65536,
 "progress": [],
 "queued": [],
 "rest": []
}

With some scripting touch /path/AutoOff.sh && chmod +x /path/AutoOff.sh

#!/bin/bash
sleep 60 >/dev/null 2>&1 #give some time to ST to connect
curl -ks -X GET -H "X-API-Key: myAPIkey" "https://localhost:8384/rest/db/need?folder=myFol-derID"|grep size >/dev/null 2>&1 #"size" is in curl output only when there is something left to sync
if [[ $? = 1 ]]; then /sbin/shutdown >/dev/null 2>&1
fi 

running from root’s crontab */15 * * * * /path/AutoOff.sh >/dev/null 2>&1

In the end I did it myself