The script you wrote in your question has a small problem. It doesn't wait for compute.service to stop before starting sensor.service.
Strategies
Here are four strategies. I think the third one is my favorite.
Find another means of concurrency
I'm not sure that stopping sensor.service is necessary. It sounds like the reason you would do this is so that new data doesn't affect the computation. In that case, I'd take a snapshot of the data file. Then compute off of that snapshot. That snapshot won't update during the compute process, solving your concurrency problem. Using PrivateTmp= means that your /tmp is actually a fresh temporary mount which is deleted when the service stops.
# /etc/systemd/system/compute.service
[Service]
ExecStartPre=/bin/cp /var/lib/sensor/data /tmp/data_to_compute
ExecStart=/usr/bin/compute /tmp/data_to_compute
PrivateTmp=yes
Do it all in a timed script
If it really is necessary to stop sensor.service, your script idea isn't bad. I'd probably make compute.timer which calls compute.service which contains ExecStart=/usr/local/bin/compute.sh. That would contain something like this:
#!/bin/sh
systemctl stop sensor.service
/usr/bin/compute /var/lib/sensor/data
systemctl start sensor.service
Use systemd relationships
In the previous example, we called systemctl from inside a script run by systemd. Something about that just doesn't feel right. The Conflicts= relationship in systemd means that when the service is started, it will automatically stop the conflicting service. systemd doesn't have a relationship to start a process when another finishes, so we can use ExecStartPost= for that here:
Therefore adding this to compute.service:
[Unit]
Conflicts=sensor.service
[Service]
ExecStart=/usr/bin/compute /var/lib/sensor/data
ExecStopPost=systemctl start sensor.service
will achieve your goal of stopping sensor.service whenever compute.timer triggers. Instead of a custom shell script, we have moved everything into the unit file. The discomfort of using systemctl from inside of systemd isn't solved, but at least we've reduced it and made it more transparent (instead of hiding it in a script).
Two timers
This is a little in-elegant, but if you want to replace the ExecStopPost= line, you could have two timers. compute.timer is set to compute as frequently as you like (just like you are already doing). If you want to compute 5 minutes worth of data, then set sensor.timer to launch sensor.service 5 minutes earlier than you trigger compute.timer.
Putting it all togeather
Regardless of the strategy, you'll need compute.timer and compute.service, but shouldn't need to touch sensor.service. I realized that you might have been asking how to make a systemd timer. Here is how I would completely implement strategy 3:
# /etc/systemd/system/compute.timer
[Unit]
Description=Timer to trigger computations every 15 minutes
[Timer]
OnCalendar=*:0/15
[Install]
WantedBy=timers.target
compute.timer (above) will start compute.service (below) every 15 minutes.
# /etc/systemd/system/compute.service
[Unit]
Description=Runs computation (triggered by compute.timer)
Conflicts=sensor.service
[Service]
ExecStart=/usr/bin/compute /var/lib/sensor/data
ExecStopPost=systemctl start sensor.service
Then just enable the timer (and start if you don't want to reboot):
systemctl enable compute.timer
systemctl start compute.timer