ParkSquare.SkyTv 8.0.0

dotnet add package ParkSquare.SkyTv --version 8.0.0                
NuGet\Install-Package ParkSquare.SkyTv -Version 8.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ParkSquare.SkyTv" Version="8.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ParkSquare.SkyTv --version 8.0.0                
#r "nuget: ParkSquare.SkyTv, 8.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ParkSquare.SkyTv as a Cake Addin
#addin nuget:?package=ParkSquare.SkyTv&version=8.0.0

// Install ParkSquare.SkyTv as a Cake Tool
#tool nuget:?package=ParkSquare.SkyTv&version=8.0.0                

SkyQ TV Box C# Remote Control & Record

Build Status


Control SkyQ set-top box over the network. Supports all remote control commands including power on/off, change channel, play/pause/stop/record, show program guide, box office and UI navigation. Retrieve box information such as device manufacturer, model and software version. View all Sky electronic programme guide (EPG) channel information and programme guide data, search for what's on now/next. Schedule recordings, list and delete recordings.

Getting Started

There are essentially three components: DeviceDiscovery, ApiClient, RemoteControl. Note that this package only works with SkyQ boxes, support for the old SkyHD and Sky+ boxes was removed from v4 onwards.

Device Discovery (UPnP)

This uses UPnP/SSDP to find devices on your network. The IP addresses of any that are identified as Sky boxes are returned. Devices will periodically advertise their existence, so you need to choose a timeframe long enough to receive them - usually a few seconds is enough.

Get Client IP Address

First, get all IP addresses for the current device (e.g. the dev machine you're running on). You can skip this section and hardcode an IP address if preferred.

var clientIpAddresses = new List<IPAddress>();

foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    if (netInterface.OperationalStatus != OperationalStatus.Up) continue;

    var ipProps = netInterface.GetIPProperties();

    foreach (var addr in ipProps.UnicastAddresses)
        if (addr.Address.AddressFamily == AddressFamily.InterNetwork)

Find SkyQ Boxes

Now find the SkyQ boxes on the network.

IReadOnlyCollection<IPAddress> boxIpAddresses;

// Find SkyQ boxes on the network

using (var deviceDiscovery = new DeviceDiscovery())
    Console.WriteLine("Looking for SkyQ boxes on network...");

    boxIpAddresses = await deviceDiscovery.FindSkyBoxesAsync(clientIpAddresses, TimeSpan.FromSeconds(3));

if (!boxIpAddresses.Any())
    Console.WriteLine("No SkyQ boxes found!");

Set Top Box Control

An API running on each SkyQ box exposes certain information and functions. An ApiClient instance can be created directly, or if using Dependency Injection, using the ApiClientFactory. The recommended method is to automatically discover the device IP address using the method above, but this is not mandatory - it can also be created using a standard HttpClient and an IPAddress you construct yourself:

var apiClient = new ApiClient(_httpClient, ipAddress);

Once you have an ApiClient, you can query details about the box, get, schedule and remove PVR recordings.


This call returns various bits of information about your SkyQ box, such as MAC address, software versions, make and model, and whether it is currently in standby mode or not.

var restClient = new RestClient(new HttpClient());
var apiClientFactory = new ApiClientFactory(restClient);

foreach (var boxIpAddress in boxIpAddresses)

    // Get box info

    var apiClient = apiClientFactory.CreateClient(boxIpAddress);
    var box = await apiClient.GetBoxDetailsAsync();

    Console.WriteLine($"{box.IpAddress} {box.MacAddress} {box.Manufacturer} {box.ModelNumber} " +
    $"Up time: {box.SystemUptime} 4K Enabled: {box.UhdCapable} {box.PowerStatus}");

Sample output: 78:3E:53:XX:XX:XX Sky Q170.000.23.00L (5dhxxxx) Up time: 11:04:15 4K Enabled: True Standby


This call gets a list of all PVR recordings on the box, which includes ones that have been deleted but not yet erased. If the item has been deleted, the IsDeleted flag will be set, the DeletedOn property will be present, and the date/time at which the item will be permanently removed is in the ExpiresOn property. The `PvrId is a unique identifier for that particular recording on your box, and can be used by other calls.

var restClient = new RestClient(new HttpClient());
var apiClientFactory = new ApiClientFactory(restClient);

foreach (var boxIpAddress in boxIpAddresses)

    var recordings = await apiClient.GetRecordingsAsync();

    foreach (var recording in recordings)
        Console.WriteLine($"{recording.Title} Season {recording.SeasonNumber} Episode {recording.EpisodeNumber}");

Sample output:

Brassic Season 1 Episode 1
Brassic Season 1 Episode 2
Brassic Season 1 Episode 3
The Fresh Prince Of Bel-Air Season 4 Episode 7
The Fresh Prince of Bel-Air Season 4 Episode 7
The Fresh Prince Of Bel-Air Season 4 Episode 8


This method tells the PVR to record a programme, or 'events' as they are known in Sky parlance. The EventId passed in to identify the programme can be found in the EPG listings search discussed later. An optional flag called SeriesLink can be specified to tell the box to link all future episodes and record them automatically. This option is false by default, so only the individual programme will be recorded.

var success = await apiClient.RecordProgrammeAsync("E708-7a0", true);


This method stops an in-progress recording, but does will not delete the partially recorded programme, instead leaving it on the box to watch.

var success = await apiClient.CancelRecordingAsync("pvr-1234");


This will delete the recording. By default, it will only soft delete the recording. There is an optional PermanentlyDelete parameter that will force the item to be erased from the disk immediately.

var success = await apiClient.DeleteRecordingAsync("pvrid1234", true);


This call returns the amount of disk space available and used.

var storageStatus = await apiClient.GetStorageStatusAsync();
Console.WriteLine($"{storageStatus.UsedMb} Mb used of {storageStatus.QuotaMb} Mb ({storageStatus.PercentageUsed} %)");

Sample output:

20262 Mb used of 675048 Mb (3.00 %)


This call returns the current time according to the set-top box, in both UTC and local timezones.

var time = await apiClient.GetTimeAsync();
Console.WriteLine($"{time.Utc} {time.Local}");


This call returns a list of all channels on the box, including audio only (radio) services.

var services = await apiClient.GetServicesAsync();

foreach (var service in services)
    Console.WriteLine($"{service.ChannelId} " +
                      $"{service.ChannelNumber} " +
                      $"{service.Description} " +
                      $"{service.PictureQuality} " +

Sample output:

Box is in standby, switching on....
2104 101 BBC One Yorks StandardDefinition Video
2075 102 BBC Two HD HighDefinition Video
1044 103 ITV HD HighDefinition Video
1624 104 Channel 4 StandardDefinition Video
4058 105 Channel 5 HD HighDefinition Video

Remote Control

The RemoteControl object allows remote control of the SkyQ box over your network by IP address. The available commands more or less mimic those found on the physical remote control, a list of which can be found in the RemoteCommand enum. Note that remote commands are ignored if the box is in standby. You can use the PowerStatus property from GetBoxDetailsAsync() above to determine if the box needs powering on before sending commands. The example below switches the box to Channel 409 (Sky Sports News), and brings the box out of standby if necessary using the result of GetBoxDetailsAsync() above.

var remoteControl = new RemoteControl(boxIpAddress);

if (box.PowerStatus == PowerStatus.Standby)
	Console.WriteLine("Box is in standby, switching on....");
	await remoteControl.SendCommandAsync(RemoteCommand.Power, RemoteCommand.Backup);

await remoteControl.SendCommandAsync(
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
8.0.0 84 6/22/2024
5.0.15 1,657 8/19/2022
5.0.14 1,546 11/22/2021
5.0.12 1,426 5/16/2021
5.0.10 1,320 4/19/2021
4.1.6 2,291 11/26/2019
4.1.5 1,558 11/26/2019
4.1.0 1,710 11/26/2019
4.0.2 1,765 11/25/2019
4.0.1 1,695 11/24/2019
4.0.0 1,753 11/23/2019
3.1.0 1,589 9/12/2019
3.0.3 1,623 7/2/2019
3.0.2 1,610 6/5/2019
3.0.1 1,579 6/4/2019
3.0.0 1,737 6/4/2019