support system wake on recording schedule

pull/702/head
Luke Pulverenti 9 years ago
parent f380ddc558
commit 657e90c98b

@ -266,6 +266,7 @@
<Compile Include="Playlists\IPlaylistManager.cs" />
<Compile Include="Playlists\Playlist.cs" />
<Compile Include="Plugins\ILocalizablePlugin.cs" />
<Compile Include="Power\IPowerManagement.cs" />
<Compile Include="Providers\AlbumInfo.cs" />
<Compile Include="Providers\ArtistInfo.cs" />
<Compile Include="Providers\BookInfo.cs" />

@ -0,0 +1,13 @@
using System;
namespace MediaBrowser.Controller.Power
{
public interface IPowerManagement
{
/// <summary>
/// Schedules the wake.
/// </summary>
/// <param name="utcTime">The UTC time.</param>
void ScheduleWake(DateTime utcTime);
}
}

@ -28,6 +28,7 @@ using System.Threading;
using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Power;
namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
@ -55,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public static EmbyTV Current;
public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder)
public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ISecurityManager security, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder, IPowerManagement powerManagement)
{
Current = this;
@ -75,7 +76,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
_recordingProvider = new ItemDataProvider<RecordingInfo>(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "recordings"), (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase));
_seriesTimerProvider = new SeriesTimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "seriestimers"));
_timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"));
_timerProvider = new TimerManager(fileSystem, jsonSerializer, _logger, Path.Combine(DataPath, "timers"), powerManagement, _logger);
_timerProvider.TimerFired += _timerProvider_TimerFired;
}

@ -8,19 +8,23 @@ using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using CommonIO;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Power;
namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
public class TimerManager : ItemDataProvider<TimerInfo>
{
private readonly ConcurrentDictionary<string, Timer> _timers = new ConcurrentDictionary<string, Timer>(StringComparer.OrdinalIgnoreCase);
private readonly IPowerManagement _powerManagement;
private readonly ILogger _logger;
public event EventHandler<GenericEventArgs<TimerInfo>> TimerFired;
public TimerManager(IFileSystem fileSystem, IJsonSerializer jsonSerializer, ILogger logger, string dataPath)
public TimerManager(IFileSystem fileSystem, IJsonSerializer jsonSerializer, ILogger logger, string dataPath, IPowerManagement powerManagement, ILogger logger1)
: base(fileSystem, jsonSerializer, logger, dataPath, (r1, r2) => string.Equals(r1.Id, r2.Id, StringComparison.OrdinalIgnoreCase))
{
_powerManagement = powerManagement;
_logger = logger1;
}
public void RestartTimers()
@ -58,6 +62,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var timespan = RecordingHelper.GetStartTime(item) - DateTime.UtcNow;
timer.Change(timespan, TimeSpan.Zero);
ScheduleWake(item);
}
else
{
@ -74,6 +79,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
base.Add(item);
AddTimer(item);
ScheduleWake(item);
}
private void AddTimer(TimerInfo item)
@ -91,6 +97,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
StartTimer(item, timerLength);
}
private void ScheduleWake(TimerInfo info)
{
var startDate = RecordingHelper.GetStartTime(info).AddMinutes(-5);
_logger.Info("Scheduling system wake timer at {0} (UTC)", startDate);
try
{
_powerManagement.ScheduleWake(startDate);
_logger.Info("Scheduled system wake timer at {0} (UTC)", startDate);
}
catch (NotImplementedException)
{
}
catch (Exception ex)
{
_logger.ErrorException("Error scheduling wake timer", ex);
}
}
public void StartTimer(TimerInfo item, TimeSpan length)
{
StopTimer(item);

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using MediaBrowser.Controller.Power;
namespace MediaBrowser.Server.Mono.Native
{
@ -203,5 +204,18 @@ namespace MediaBrowser.Server.Mono.Native
public string sysname = string.Empty;
public string machine = string.Empty;
}
public IPowerManagement GetPowerManagement()
{
return new NullPowerManagement();
}
}
public class NullPowerManagement : IPowerManagement
{
public void ScheduleWake(DateTime utcTime)
{
throw new NotImplementedException();
}
}
}

@ -534,6 +534,8 @@ namespace MediaBrowser.Server.Startup.Common
EncodingManager = new EncodingManager(FileSystemManager, Logger, MediaEncoder, ChapterManager);
RegisterSingleInstance(EncodingManager);
RegisterSingleInstance(NativeApp.GetPowerManagement());
var sharingRepo = new SharingRepository(LogManager, ApplicationPaths);
await sharingRepo.Initialize().ConfigureAwait(false);
RegisterSingleInstance<ISharingManager>(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this));

@ -2,6 +2,7 @@
using MediaBrowser.Model.Logging;
using System.Collections.Generic;
using System.Reflection;
using MediaBrowser.Controller.Power;
namespace MediaBrowser.Server.Startup.Common
{
@ -90,5 +91,11 @@ namespace MediaBrowser.Server.Startup.Common
/// Prevents the system stand by.
/// </summary>
void PreventSystemStandby();
/// <summary>
/// Gets the power management.
/// </summary>
/// <returns>IPowerManagement.</returns>
IPowerManagement GetPowerManagement();
}
}

@ -120,6 +120,7 @@
<Compile Include="Native\Standby.cs" />
<Compile Include="Native\ServerAuthorization.cs" />
<Compile Include="Native\WindowsApp.cs" />
<Compile Include="Native\WindowsPowerManagement.cs" />
<Compile Include="Networking\CertificateGenerator.cs" />
<Compile Include="Networking\NativeMethods.cs" />
<Compile Include="Networking\NetworkManager.cs" />

@ -6,6 +6,7 @@ using MediaBrowser.ServerApplication.Networking;
using System.Collections.Generic;
using System.Reflection;
using CommonIO;
using MediaBrowser.Controller.Power;
namespace MediaBrowser.ServerApplication.Native
{
@ -117,5 +118,10 @@ namespace MediaBrowser.ServerApplication.Native
{
Standby.PreventSystemStandby();
}
public IPowerManagement GetPowerManagement()
{
return new WindowsPowerManagement();
}
}
}

@ -0,0 +1,40 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
using MediaBrowser.Controller.Power;
using Microsoft.Win32.SafeHandles;
namespace MediaBrowser.ServerApplication.Native
{
public class WindowsPowerManagement : IPowerManagement
{
[DllImport("kernel32.dll")]
public static extern SafeWaitHandle CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In] ref long pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume);
public void ScheduleWake(DateTime utcTime)
{
long duetime = utcTime.ToFileTime();
using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, true, "MyWaitabletimer"))
{
if (SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true))
{
using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset))
{
wh.SafeWaitHandle = handle;
wh.WaitOne();
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
}
}
Loading…
Cancel
Save