getting started with EssentialsTechRoom

This commit is contained in:
Andrew Welker
2020-12-01 16:20:59 -07:00
parent f283f82bbc
commit 008a052045
4 changed files with 291 additions and 163 deletions

View File

@@ -22,30 +22,25 @@ namespace PepperDash.Essentials.Room.Config
public static Device GetRoomObject(DeviceConfig roomConfig) public static Device GetRoomObject(DeviceConfig roomConfig)
{ {
var typeName = roomConfig.Type.ToLower(); var typeName = roomConfig.Type.ToLower();
if (typeName == "huddle") if (typeName == "huddle")
{ {
var huddle = new EssentialsHuddleSpaceRoom(roomConfig); return new EssentialsHuddleSpaceRoom(roomConfig);
return huddle;
} }
else if (typeName == "huddlevtc1") if (typeName == "huddlevtc1")
{ {
var rm = new EssentialsHuddleVtc1Room(roomConfig); return new EssentialsHuddleVtc1Room(roomConfig);
}
if (typeName == "ddvc01Bridge")
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
if (typeName == "dualdisplay")
{
return new EssentialsDualDisplayRoom(roomConfig);
}
return rm; return typeName != "techRoom" ? null : new EssentialsTechRoom(roomConfig);
}
else if (typeName == "ddvc01Bridge")
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
else if (typeName == "dualdisplay")
{
var rm = new EssentialsDualDisplayRoom(roomConfig);
return rm;
}
return null;
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,20 @@
using System.Collections.Generic;
namespace PepperDash.Essentials.Room.Config
{
public class EssentialsTechRoomConfig
{
public List<string> Displays;
public List<string> Tuners;
public string ScheduleProviderKey;
public string UserPin;
public string TechPin;
public string PresetsFileName;
public EssentialsTechRoomConfig()
{
Displays = new List<string>();
Tuners = new List<string>();
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public class EssentialsTechRoom:EssentialsRoomBase
{
private Dictionary<string, IRSetTopBoxBase> _tuners;
private Dictionary<string, TwoWayDisplayBase> _displays;
private DevicePresetsModel _tunerPresets;
private readonly EssentialsTechRoomConfig _config;
public EssentialsTechRoom(DeviceConfig config) : base(config)
{
_config = config.Properties.ToObject<EssentialsTechRoomConfig>();
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName);
_tuners = GetDevices<IRSetTopBoxBase>(_config.Tuners);
_displays = GetDevices<TwoWayDisplayBase>(_config.Displays);
}
private Dictionary<string, T> GetDevices<T>(ICollection<string> config) where T:IKeyed
{
try
{
var returnValue = DeviceManager.AllDevices.OfType<T>()
.Where(d => config.Contains(d.Key))
.ToDictionary(d => d.Key, d => d);
return returnValue;
}
catch
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error getting devices. Check Essentials Configuration");
return null;
}
}
#region Overrides of EssentialsRoomBase
protected override Func<bool> IsWarmingFeedbackFunc
{
get { throw new NotImplementedException(); }
}
protected override Func<bool> IsCoolingFeedbackFunc
{
get { throw new NotImplementedException(); }
}
protected override Func<bool> OnFeedbackFunc
{
get { throw new NotImplementedException(); }
}
protected override void EndShutdown()
{
throw new NotImplementedException();
}
public override void SetDefaultLevels()
{
throw new NotImplementedException();
}
public override void PowerOnToDefaultOrLastSource()
{
throw new NotImplementedException();
}
public override bool RunDefaultPresentRoute()
{
throw new NotImplementedException();
}
public override void RoomVacatedForTimeoutPeriod(object o)
{
throw new NotImplementedException();
}
#endregion
}
}

View File

@@ -1,178 +1,197 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
//using SSMono.IO; //using SSMono.IO;
namespace PepperDash.Essentials.Core.Presets namespace PepperDash.Essentials.Core.Presets
{ {
/// <summary> /// <summary>
/// Class that represents the model behind presets display /// Class that represents the model behind presets display
/// </summary> /// </summary>
public class DevicePresetsModel : Device public class DevicePresetsModel : Device
{ {
public event EventHandler PresetsLoaded; private readonly bool _initSuccess;
public int PulseTime { get; set; } /// <summary>
public int DigitSpacingMS { get; set; } /// The methods on the STB device to call when dialing
public bool PresetsAreLoaded { get; private set; } /// </summary>
private Dictionary<char, Action<bool>> _dialFunctions;
public List<PresetChannel> PresetsList { get { return _PresetsList.ToList(); } } private bool _dialIsRunning;
List<PresetChannel> _PresetsList; private Action<bool> _enterFunction;
public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } } private string _filePath;
public bool UseLocalImageStorage { get; set; } public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
public string ImagesLocalHostPrefix { get; set; } : this(key, fileName)
public string ImagesPathPrefix { get; set; } {
public string ListPathPrefix { get; set; } try
{
// Grab the digit functions from the device
// If any fail, the whole thing fails peacefully
_dialFunctions = new Dictionary<char, Action<bool>>(10)
{
{'1', setTopBox.Digit1},
{'2', setTopBox.Digit2},
{'3', setTopBox.Digit3},
{'4', setTopBox.Digit4},
{'5', setTopBox.Digit5},
{'6', setTopBox.Digit6},
{'7', setTopBox.Digit7},
{'8', setTopBox.Digit8},
{'9', setTopBox.Digit9},
{'0', setTopBox.Digit0},
{'-', setTopBox.Dash}
};
}
catch
{
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
_dialFunctions = null;
return;
}
/// <summary> _enterFunction = setTopBox.KeypadEnter;
/// The methods on the STB device to call when dialing }
/// </summary>
Dictionary<char, Action<bool>> DialFunctions;
Action<bool> EnterFunction;
bool DialIsRunning; public DevicePresetsModel(string key, string fileName) : base(key)
string FilePath; {
bool InitSuccess; PulseTime = 150;
//SSMono.IO.FileSystemWatcher ListWatcher; DigitSpacingMs = 150;
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName) UseLocalImageStorage = true;
: base(key)
{
PulseTime = 150;
DigitSpacingMS = 150;
try ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
{ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
// Grab the digit functions from the device ImagesPathPrefix = @"/presets/images.zip/";
// If any fail, the whole thing fails peacefully ListPathPrefix = @"/html/presets/lists/";
DialFunctions = new Dictionary<char, Action<bool>>(10)
{
{ '1', setTopBox.Digit1 },
{ '2', setTopBox.Digit2 },
{ '3', setTopBox.Digit3 },
{ '4', setTopBox.Digit4 },
{ '5', setTopBox.Digit5 },
{ '6', setTopBox.Digit6 },
{ '7', setTopBox.Digit7 },
{ '8', setTopBox.Digit8 },
{ '9', setTopBox.Digit9 },
{ '0', setTopBox.Digit0 },
{ '-', setTopBox.Dash }
};
}
catch
{
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
DialFunctions = null;
return;
}
EnterFunction = setTopBox.KeypadEnter; SetFileName(fileName);
UseLocalImageStorage = true; _initSuccess = true;
}
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter( public int PulseTime { get; set; }
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0); public int DigitSpacingMs { get; set; }
ImagesPathPrefix = @"/presets/images.zip/"; public bool PresetsAreLoaded { get; private set; }
ListPathPrefix = @"/html/presets/lists/";
SetFileName(fileName); public List<PresetChannel> PresetsList { get; private set; }
//ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists"); public int Count
//ListWatcher.NotifyFilter = NotifyFilters.LastWrite; {
//ListWatcher.EnableRaisingEvents = true; get { return PresetsList != null ? PresetsList.Count : 0; }
//ListWatcher.Changed += ListWatcher_Changed; }
InitSuccess = true;
} public bool UseLocalImageStorage { get; set; }
public string ImagesLocalHostPrefix { get; set; }
public string ImagesPathPrefix { get; set; }
public string ListPathPrefix { get; set; }
public event EventHandler PresetsLoaded;
public void SetFileName(string path) public void SetFileName(string path)
{ {
FilePath = ListPathPrefix + path; _filePath = ListPathPrefix + path;
LoadChannels(); LoadChannels();
} }
public void LoadChannels() public void LoadChannels()
{ {
PresetsAreLoaded = false; PresetsAreLoaded = false;
try try
{ {
var pl = JsonConvert.DeserializeObject<PresetsList>(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII)); var pl = JsonConvert.DeserializeObject<PresetsList>(File.ReadToEnd(_filePath, Encoding.ASCII));
Name = pl.Name; Name = pl.Name;
_PresetsList = pl.Channels; PresetsList = pl.Channels;
} }
catch (Exception e) catch (Exception e)
{ {
Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message); Debug.Console(2, this,
// Just save a default empty list "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
_PresetsList = new List<PresetChannel>(); _filePath, e.Message);
} // Just save a default empty list
PresetsAreLoaded = true; PresetsList = new List<PresetChannel>();
}
PresetsAreLoaded = true;
var handler = PresetsLoaded; var handler = PresetsLoaded;
if (handler != null) if (handler != null)
handler(this, EventArgs.Empty); {
} handler(this, EventArgs.Empty);
}
}
public void Dial(int presetNum) public void Dial(int presetNum)
{ {
if (presetNum <= _PresetsList.Count) if (presetNum <= PresetsList.Count)
Dial(_PresetsList[presetNum - 1].Channel); {
} Dial(PresetsList[presetNum - 1].Channel);
}
}
public void Dial(string chanNum) public void Dial(string chanNum)
{ {
if (DialIsRunning || !InitSuccess) return; if (_dialIsRunning || !_initSuccess)
if (DialFunctions == null) {
{ return;
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key); }
return; if (_dialFunctions == null)
} {
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
return;
}
DialIsRunning = true; _dialIsRunning = true;
CrestronInvoke.BeginInvoke(o => CrestronInvoke.BeginInvoke(o =>
{ {
foreach (var c in chanNum.ToCharArray()) foreach (var c in chanNum.ToCharArray())
{ {
if (DialFunctions.ContainsKey(c)) if (_dialFunctions.ContainsKey(c))
Pulse(DialFunctions[c]); {
CrestronEnvironment.Sleep(DigitSpacingMS); Pulse(_dialFunctions[c]);
} }
CrestronEnvironment.Sleep(DigitSpacingMs);
}
if (EnterFunction != null) if (_enterFunction != null)
Pulse(EnterFunction); {
DialIsRunning = false; Pulse(_enterFunction);
}); }
} _dialIsRunning = false;
});
}
void Pulse(Action<bool> act) public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
{ {
act(true); _dialFunctions = new Dictionary<char, Action<bool>>(10)
CrestronEnvironment.Sleep(PulseTime); {
act(false); {'1', setTopBox.Digit1},
} {'2', setTopBox.Digit2},
{'3', setTopBox.Digit3},
{'4', setTopBox.Digit4},
{'5', setTopBox.Digit5},
{'6', setTopBox.Digit6},
{'7', setTopBox.Digit7},
{'8', setTopBox.Digit8},
{'9', setTopBox.Digit9},
{'0', setTopBox.Digit0},
{'-', setTopBox.Dash}
};
/// <summary> _enterFunction = setTopBox.KeypadEnter;
/// Event handler for filesystem watcher. When directory changes, this is called
/// </summary> Dial(chanNum);
//void ListWatcher_Changed(object sender, FileSystemEventArgs e) }
//{
// Debug.Console(1, this, "folder modified: {0}", e.FullPath); private void Pulse(Action<bool> act)
// if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase)) {
// { act(true);
// Debug.Console(1, this, "File changed: {0}", e.ChangeType); CrestronEnvironment.Sleep(PulseTime);
// LoadChannels(); act(false);
// } }
//} }
}
} }