FetchTV python library Compatible with Python 3.7
Connects to the FetchTV ecosystem allowing:
- Sending commands to a Fetch Box
- Recording free-to-air (FTA) programs
- Listing and deleting recordings
The API retrieves and maintains the FetchTV data locally. The primary classes are:
-
FetchTV - Primary object to interact with FetchTV
- Login with authorisation code and PIN
- Access a FetchTV Box
- Access the Electronic Program Guide (EPG)
- Subscribe a callback for events
-
FetchTvBox - Represents a FetchTV box, allowing checking state and calling functions.
- Returned from FetchTV by:
fetchtv.get_boxes(), fetchtv.get_box(<terminal_id>)
- Send Remote Key (Play, Pause, etc...)
- Record/Cancel a program
- List/delete recordings
- Record/Cancel a series
- Returned from FetchTV by:
Add the respective version to your requirements.txt
file
git+https://github.com/jinxo13/pyfetchtv@v0.3.0#egg=pyfetchtv
Refer to the examples in test/examples
import os
import pprint
import sys
import time
import logging
from os.path import join, dirname
from dotenv import load_dotenv
from pyfetchtv.api.const.remote_keys import RemoteKey
from pyfetchtv.api.fetchtv import FetchTV
from pyfetchtv.api.fetchtv_box_interface import RecordProgramParameters
from pyfetchtv.api.fetchtv_interface import SubscriberMessage
from pyfetchtv.api.json_objects.set_top_box import PlayState
CMD_DELAY = 5
pp = pprint.PrettyPrinter(indent=2)
dotenv_path = join(dirname(__file__), '../.env')
load_dotenv(dotenv_path)
logger = logging.getLogger()
# logger.level = logging.DEBUG
# stream_handler = logging.StreamHandler(sys.stdout)
# logger.addHandler(stream_handler)
def callback(msg: SubscriberMessage):
print(f'Received Message: {msg.group} - {msg.command}')
print('-->' + str(msg.message))
if __name__ == "__main__":
fetchtv = FetchTV(ping_sec=60)
fetchtv.add_subscriber('me', callback)
print(f'\n--> Login to FetchTV')
if not fetchtv.login(os.environ.get('ACTIVATION_CODE'), os.environ.get('PIN')):
logger.error('Login to FetchTV failed, check activation code and pin are correct.')
exit(1)
try:
# Wait for box
for _ in range(10):
if len(fetchtv.get_boxes()) > 0:
break
time.sleep(1)
if len(fetchtv.get_boxes()) == 0:
logger.error('No boxes found. Check your FetchTV box is on.')
exit(0)
# Print box status
terminal_id = ''
print(f'\n--> FetchTV Boxes')
for box in fetchtv.get_boxes().values():
print(f'Box Id: {box.terminal_id}, Name: {box.label}')
print('-->' + str(box.state.to_dict()))
if not terminal_id:
terminal_id = box.terminal_id
# Turn on
box = fetchtv.get_box(terminal_id)
if box.state.play_state == PlayState.IDLE:
print(f'\n--> Turning {box.label} on.')
box.send_key(RemoteKey.Power)
time.sleep(CMD_DELAY)
# Pause
print(f'\n--> Pause')
box.send_key(RemoteKey.PlayPause)
time.sleep(CMD_DELAY)
# Play
print(f'\n--> Play')
box.send_key(RemoteKey.PlayPause)
time.sleep(CMD_DELAY)
# Stop (goes back to live TV)
print(f'\n--> Stop')
box.send_key(RemoteKey.Stop)
time.sleep(CMD_DELAY)
# Retrieve current program
program = box.get_current_program()
if not program:
logger.error(f'No current program TV found on FetchTV box {box.label}.')
exit(1)
print(f'\n--> Current program')
print(program.to_dict())
# Record current program
print(f'\n--> Record current program')
box.record_program(RecordProgramParameters(
channel_id=box.state.channel_id,
program_id=program.program_id,
epg_program_id=program.epg_program_id))
time.sleep(CMD_DELAY)
# List recordings for today
print(f'\n--> Recordings...')
pp.pprint([rec.name for rec in box.recordings.future.values()])
# Cancel recording
print(f'\n--> Cancel recording')
box.cancel_recording(program.program_id)
time.sleep(CMD_DELAY)
# List stored recording
print(f'\n--> Stored recording')
pp.pprint([rec.dlna_url for rec in box.recordings.items.values() if rec.program_id == program.program_id
and not rec.pending_delete])
# Delete recording
print(f'\n--> Delete recording')
recording_ids = [rec.id for rec in box.recordings.items.values()
if rec.program_id == program.program_id and not rec.pending_delete]
box.delete_recordings(recording_ids)
time.sleep(CMD_DELAY)
finally:
fetchtv.close()