[Solved] checking if recording is in process before restarting backend

For discussion of topics specific to MythTV on linux
Post Reply
cliveb
Senior
Posts: 131
Joined: Fri Jan 08, 2016 9:59 am
Great Britain

[Solved] checking if recording is in process before restarting backend

Post by cliveb »

Not sure if this belongs here in the Linux section or the Raspberry Pi one.
I'm running 0.31 on a RPi4, but the question seems to be generic to Linux.

I use the OTA EIT data to gather listings, and for as long as I can remember (even on older versions running on different hardware) it's been the case that it works fine for several weeks and then suddenly, for reasons I can't fathom, it just stops gathering the EIT data. There seems to be no pattern to when this happens. Restarting the backend fixes things.

Up to now I've just gone in and restarted the backend manually, but it would be much simpler to just add a cron job to do it once a week. The problem is, I don't want that cron job to fire if the backend happens to be recording anything (or is due to start a recording in the next few minutes). I could write a bash script to do the necessary check, but how does one check whether a recording is running or about to start? Or maybe there's a simpler solution that I'm missing. Can anyone suggest a suitable approach?
User avatar
heyted
Senior
Posts: 301
Joined: Sun Jun 08, 2014 2:14 am
Location: South Florida
Contact:
United States of America

Re: checking if recording is in process before restarting backend

Post by heyted »

If no recordings are happening late at night, have it reboot then. In Ubuntu, no cron job is needed. Not sure about other distros. In Ubuntu, Startup Applications Preferences, bash -c "sudo shutdown -r 03:00" can be entered to reboot every night at 3:00 AM. An /etc/sudoers file modification is needed.
Ted | My blog
cliveb
Senior
Posts: 131
Joined: Fri Jan 08, 2016 9:59 am
Great Britain

Re: checking if recording is in process before restarting backend

Post by cliveb »

heyted wrote:
Thu Dec 30, 2021 12:59 am
If no recordings are happening late at night, have it reboot then. In Ubuntu, no cron job is needed. Not sure about other distros. In Ubuntu, Startup Applications Preferences, bash -c "sudo shutdown -r 03:00" can be entered to reboot every night at 3:00 AM. An /etc/sudoers file modification is needed.
Thanks for the suggestion, but I certainly don't want to reboot the machine. This is a RPi4 with devices attached via a USB3 powered hub. A reboot needs the hub to be disconnected until it gets past the initial power up phase, then reconnected to actually boot. So an unattended reboot will certainly fail.

I just want to restart the myth backend service. And if I knew there were never going to be recordings overnight I could easily set up a Cron job to do the service restart once a week at, say, 4am. But although it's extremely unlikely that any recordings will be going at that time, it's not certain. So a way to check before initiating the restart is what I'm looking for.
User avatar
heyted
Senior
Posts: 301
Joined: Sun Jun 08, 2014 2:14 am
Location: South Florida
Contact:
United States of America

Re: checking if recording is in process before restarting backend

Post by heyted »

Okay. Understood. Maybe the GetUpcomingList API could help with this.

https://www.mythtv.org/wiki/DVR_Service#GetUpcomingList

The Mythrecmaze Python script uses a similar API call.

https://github.com/heyted/mythrecmaze/b ... recmaze.py
Ted | My blog
User avatar
paulh
Developer
Posts: 909
Joined: Thu Feb 06, 2014 6:09 pm
Great Britain

Re: checking if recording is in process before restarting backend

Post by paulh »

You could also use mythshutdown --check or mythshutdown --status to see if the backend is busy.
cliveb
Senior
Posts: 131
Joined: Fri Jan 08, 2016 9:59 am
Great Britain

Re: checking if recording is in process before restarting backend

Post by cliveb »

paulh wrote:
Fri Dec 31, 2021 1:14 pm
You could also use mythshutdown --check or mythshutdown --status to see if the backend is busy.
Many thanks. Just checked that out and it looks to be the best option.

As far as I can see, there isn't a way to check if a recording is due to start in the next few minutes - only if something is currently recording.
But it will do the job in all but pathalogical circumstances. If I set the cron job to run at some strange time like 04:12, seems very unlikely there'll be anything due to start recording between then and 04:15.

Happy New Year!
User avatar
bill6502
Developer
Posts: 2299
Joined: Fri Feb 07, 2014 5:28 pm
United States of America

Re: checking if recording is in process before restarting backend

Post by bill6502 »

The Dvr/GetUpcomingList endpoint mentioned above will return enough
information to find the next start time and compare it to the current time.

curl --header Accept:application/json --silent localhost:6544/Dvr/GetUpcomingList?Count=1|jsonlint --format --nonstrict
cliveb
Senior
Posts: 131
Joined: Fri Jan 08, 2016 9:59 am
Great Britain

Re: checking if recording is in process before restarting backend

Post by cliveb »

bill6502 wrote:
Mon Jan 03, 2022 10:43 pm
The Dvr/GetUpcomingList endpoint mentioned above will return enough
information to find the next start time and compare it to the current time.

curl --header Accept:application/json --silent localhost:6544/Dvr/GetUpcomingList?Count=1|jsonlint --format --nonstrict
Thanks for that tip. My server doesn't appear to have jsonlint installed, but I should be able to use bash scripting to save the output and then locate the StartTs value to check if the next recording is imminent.
User avatar
bill6502
Developer
Posts: 2299
Joined: Fri Feb 07, 2014 5:28 pm
United States of America

Re: checking if recording is in process before restarting backend

Post by bill6502 »

jsonlint is just to make the output easy to read. Otherwise, it's all on one line.

This is a python3 script that will see if the backend is recording or about to record. See the comments.

Code: Select all

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
See if the backend is not recording or near recording

File: safe_restart_mythtv_backend.py

Example: safe_restart_mythtv_backend.py Also try --help.

Returns:   0 OK to restart
           1 the next program starts before now + restart time
         255 this program can't determine the time (error case)

Verbose timestamps are in UTC.
'''

import argparse
from datetime import datetime, timedelta
import sys
import dateutil.parser
from MythTV.services_api import send as api


def parse_command_line():
    ''' Get switches from the command line. '''

    parser = argparse.ArgumentParser(
        description='Check for idle time before next recording.',
        epilog='Default values are in ()s.')

    parser.add_argument('--restarttime', type=int, metavar='<min>', default=10,
                        help='allow (%(default)s) minutes for a restart')

    parser.add_argument('--host', type=str, metavar='<host>',
                        default='localhost',
                        help='server hostname or IP address (%(default)s)')

    parser.add_argument('--port', type=int, metavar='<port>', default=6544,
                        help='backend port (%(default)i)')

    parser.add_argument('--verbose', action='store_true',
                        help='explain what is being done (%(default)s)')

    parser.add_argument('--version', action='version',
                        version='%(prog)s v{} '.format(0.5))

    return parser.parse_args()


def print_exit(code, message, verbose):
    ''' Optionally print a message then exit with the supplied code. '''

    if verbose and message:
        print(message)

    sys.exit(code)


def main():
    ''' Get next recording details, get the current time and report status. '''

    args = parse_command_line()

    backend = api.Send(host=args.host, port=args.port)

    try:
        response = backend.send(endpoint='Dvr/GetUpcomingList', rest='Count=1')
    except RuntimeError:
        print_exit(255, 'Connection to mythbackend failed.', args.verbose)

    if int(response['ProgramList']['Count']) == 0:
        print_exit(0, 'No Upcoming Recordings.', args.verbose)

    restart_time = timedelta(0, 0, 0, 0, args.restarttime, 0)

    ascii_ts = response['ProgramList']['Programs'][0]['Recording']['StartTs']

    next_recording_starttime = dateutil.parser.parse(ascii_ts, ignoretz=True)
    now = datetime.utcnow()

    if args.verbose:
        print('\nProgram Start: {}\n\t  Now: {}\n  Boot Length: {}\n'.
              format(next_recording_starttime.strftime("%F %R"),
                     now.strftime("%F %R"),
                     restart_time))

    if (now + restart_time) < next_recording_starttime:
        print_exit(0, 'OK To Restart MythTV Backend.', args.verbose)

    print_exit(1, 'Too Close To Next Recording.', args.verbose)


if __name__ == '__main__':
    main()

# vim: set expandtab tabstop=4 shiftwidth=4 smartindent colorcolumn=80:
cliveb
Senior
Posts: 131
Joined: Fri Jan 08, 2016 9:59 am
Great Britain

Re: checking if recording is in process before restarting backend

Post by cliveb »

bill6502 wrote:
Fri Jan 07, 2022 4:20 pm
jsonlint is just to make the output easy to read. Otherwise, it's all on one line.

This is a python3 script that will see if the backend is recording or about to record. See the comments.
[snip]
Thanks for the suggested python code, but it's fairly straightforward to just use bash scripting.
I decided to grab the data in XML rather than JSON format.

Code: Select all

#!/bin/bash
# get data about current / next scheduled recording:
INFO=`curl --header Accept:application/html --silent localhost:6544/Dvr/GetUpcomingList?Count=1`
# extract date/time when current recording started or next recording starts -
#   find the position of <StartTs> and grab its value:
PFX=${INFO%%<StartTs>*}
POSN=${#PFX}
RECTIME=${INFO:POSN+9:19}
# convert the recording start time to the epoch time:
RECSECS=`date --date $RECTIME +%s`
# get the current epoch time:
NOWSECS=`date +%s`
# difference is number of seconds before next recording starts:
RECIN=`expr $RECSECS - $NOWSECS`
if [ $RECIN -gt 300 ]; then
  # next recording is more than 5 mins away, so safe to restart backend:
  systemctl restart mythtv-backend
fi
(I appreciate that this will fail if there are no recordings scheduled, but that's never going to be the case for me).
Post Reply