2

mlrpt is a command line utility to capture data from the meteor-2 satellite. The satellite passes overhead at different times every day and I want to use systemd timers to start mlrpt with the correct arguments.

I start with times obtained from an API

    startDate start_times end_times duration
1  2019-08-25       17:51     18:05       14
2  2019-08-25       19:31     19:45       14
3  2019-08-26       05:07     05:21       14
4  2019-08-26       06:47     07:01       14
5  2019-08-26       19:11     19:25       14
6  2019-08-27       06:27     06:42       15
7  2019-08-27       18:51     19:06       15
8  2019-08-28       06:07     06:22       15
9  2019-08-28       18:31     18:46       15
10 2019-08-29       05:47     06:02       15
11 2019-08-29       18:11     18:26       15
12 2019-08-30       05:27     05:42       15
13 2019-08-30       17:51     18:06       15
14 2019-08-30       19:31     19:45       14
15 2019-08-31       05:08     05:22       14
16 2019-08-31       06:48     07:02       14
17 2019-08-31       19:11     19:26       15
18 2019-09-01       06:27     06:42       15
19 2019-09-01       18:51     19:07       16
20 2019-09-02       06:07     06:23       16
21 2019-09-02       18:31     18:47       16
22 2019-09-03       05:47     06:03       16

And for each of the times want to run mlrpt with the format mlrpt $startT-$stopT -t $durationMin

I started with this service file

~/.config/systemd/user/mlrpt.service
[Unit]
Description=Capture Meteor satellite data using mlrpt
DefaultDependencies=no
Wants=local-fs.target time-sync.target
After=local-fs.target time-sync.target

[Service]

Type=simple
ExecStart=/usr/local/bin/mlrpt $START_TIME-$END_TIME -t $DURATION

How would I set up timer files such that not only does it start mlrpt at the correct time, but also is able to pass the correct arguments to the utility (they're different each time)? I think I need a template like

~/.config/systemd/user/mlrpt.timer
[Unit]
Description=Run mlrpt when a satellite is overhead

[Timer]
OnCalendar=
Persistent=true

[Install]
WantedBy=timers.target

But don't know where to go next. I have the scripting skills to generate timer files if I have an example of what a correct timer file looks like.

4
  • Which exactly times would you want to start mlrpt? Both columns of start_times and both columns of end_time? – Vasconcelos1914 Aug 25 '19 at 14:28
  • 1
    I want to start mlrpt at each of the start_times (actually it would probably be better to start mlrpt one minute before the satellite appears). I'll edit the data to be clearer. The other columns (end_times and duration) are data I need to pass to mlrpt so it knows how long to run for. – pgcudahy Aug 25 '19 at 14:35
  • Add it please, and notify me when done. – Vasconcelos1914 Aug 25 '19 at 14:36
  • I've edited the data to be clearer. Each row is a date (startDate) and time (start_times) that I'd like the timer to fire, and it needs to be able to pass the start_times, end_times, and duration value to mlrpt as mlrpt start_times-stop_times -t duration – pgcudahy Aug 25 '19 at 14:42
1

For these onetime, non-recurring tasks, I think I found a better solution with systemd-run. For the first entry in the list, I'd write a script to run systemd-run --user --on-calendar="2019-08-25 19:51" /usr/local/bin/mlrpt "17:51-18:05" -t 14

1

A different approach would be to combine several elements in one service file (no timer). The elements are:

  • a "self-restarting" Type=oneshot service with an EnvironmentFile=/path/to/mlrpt-textfile directive that reads your mlrpt parameters for a single satellite pass encoded as customized varenvs from the "mlrpt-textfile". These parameters would be 1) $START_TIME and 2) $END_TIME for satellite pass, 3) pass $DURATION, and 4) $WAIT time until next pass.

  • two textfiles. One called, say, "mlrpt-list" with a complete list of the customized mlrpt parameters similar but not identical to your list with the 22 entries. The other text file would contain only one entry (this is the "mlrpt-textfile" mentioned above)

  • a mechanism (including a simple script) that reads the first entry from the start of the "mlrpt-list", copies it to "mlrpt-textfile", then deletes the first entry in "mlrpt-list", and repeats the same process on-demand until there is no entry left in "mlrpt-list" (note: copy to "mlrpt-textfile" should not append but overwrite).

Now, the oneshot-service file should look roughly like below to consolidate all three elements into one working solution. The main reason to use oneshot is its ability to accomodate not only one but several ExecStart= directives. By design the ExecStart directives are executed one after another. This allows us to create and execute the above mentioned "mechanism" by means of a single oneshot service unit.

# /etc/systemd/system/myservice.service

[Unit]
Description=my service Service
ConditionPathExists=/path/to/mlrpt-textfile # contains $START_TIME, $END_TIME, $WAIT,     
                                            # and $DURATION for a single pass
ConditionFileNotEmpty=/path/to/mlrpt-textfile
EnvironmentFile=/path/to/mlrpt-textfile

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mlrpt $START_TIME-$END_TIME -t $DURATION
ExecStart=/bin/sleep $WAIT
ExecStart=/path/to/script # script copies one entry from mlrpt-list to mlrpt-textfile
ExecStopPost=/bin/systemctl restart myservice.service

[Install]

Of course, this needs more refinement (e.g. dependencies need to be added as needed). The script should also be used to make the service fail after the last pass, for example by erasing the entry in "mlrpt-textfile" after the last pass (so the ConditionFileNotEmpty fails on restart).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.