chore: move all files to file-scoped namespace

This commit is contained in:
Andrew Welker 2025-07-04 16:02:32 -05:00 committed by Neil Dorin
parent aaa5b0532b
commit 3ece4f0b7b
522 changed files with 39628 additions and 45678 deletions

View file

@ -12,284 +12,40 @@ using PepperDash.Core;
using PepperDash.Core.WebApi.Presets;
using Serilog.Events;
namespace PepperDash.Essentials.Core.Presets
namespace PepperDash.Essentials.Core.Presets;
/// <summary>
/// Class that represents the model behind presets display
/// </summary>
public class DevicePresetsModel : Device
{
public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel);
public delegate void PresetsSavedCallback(List<PresetChannel> presets);
private readonly CCriticalSection _fileOps = new CCriticalSection();
private readonly bool _initSuccess;
private readonly ISetTopBoxNumericKeypad _setTopBox;
/// <summary>
/// Class that represents the model behind presets display
/// The methods on the STB device to call when dialing
/// </summary>
public class DevicePresetsModel : Device
private Dictionary<char, Action<bool>> _dialFunctions;
private bool _dialIsRunning;
private Action<bool> _enterFunction;
private string _filePath;
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
: this(key, fileName)
{
/// <summary>
/// Delegate for preset recalled event
/// </summary>
/// <param name="device">device that recalled a preset</param>
/// <param name="channel">channel that was recalled</param>
public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel);
/// <summary>
/// Delegate for presets saved event
/// </summary>
/// <param name="presets">list of presets that were saved</param>
public delegate void PresetsSavedCallback(List<PresetChannel> presets);
private readonly CCriticalSection _fileOps = new CCriticalSection();
private readonly bool _initSuccess;
private readonly ISetTopBoxNumericKeypad _setTopBox;
/// <summary>
/// The methods on the STB device to call when dialing
/// </summary>
private Dictionary<char, Action<bool>> _dialFunctions;
private bool _dialIsRunning;
private Action<bool> _enterFunction;
private string _filePath;
/// <summary>
/// Constructor
/// </summary>
/// <param name="key">key for the device</param>
/// <param name="setTopBox">set top box device</param>
/// <param name="fileName">file name for presets</param>
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
: this(key, fileName)
try
{
try
{
_setTopBox = setTopBox;
_setTopBox = setTopBox;
// 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.LogMessage(LogEventLevel.Information, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
_dialFunctions = null;
return;
}
_enterFunction = setTopBox.KeypadEnter;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="key">key for the device</param>
/// <param name="fileName">file name for presets</param>
public DevicePresetsModel(string key, string fileName) : base(key)
{
PulseTime = 150;
DigitSpacingMs = 150;
UseLocalImageStorage = true;
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
ImagesPathPrefix = @"/presets/images.zip/";
ListPathPrefix = @"/html/presets/lists/";
SetFileName(fileName);
_initSuccess = true;
}
/// <summary>
/// Event fired when a preset is recalled
/// </summary>
public event PresetRecalledCallback PresetRecalled;
/// <summary>
/// Event fired when presets are saved
/// </summary>
public event PresetsSavedCallback PresetsSaved;
/// <summary>
/// Gets or sets the PulseTime
/// </summary>
public int PulseTime { get; set; }
/// <summary>
/// Gets or sets the DigitSpacingMs
/// </summary>
public int DigitSpacingMs { get; set; }
/// <summary>
/// Gets or sets the PresetsAreLoaded
/// </summary>
public bool PresetsAreLoaded { get; private set; }
/// <summary>
/// Gets or sets the PresetsList
/// </summary>
public List<PresetChannel> PresetsList { get; private set; }
/// <summary>
/// Gets the Count of presets
/// </summary>
public int Count
{
get { return PresetsList != null ? PresetsList.Count : 0; }
}
/// <summary>
/// Gets or sets the UseLocalImageStorage
/// </summary>
public bool UseLocalImageStorage { get; set; }
/// <summary>
/// Gets or sets the ImagesLocalHostPrefix
/// </summary>
public string ImagesLocalHostPrefix { get; set; }
/// <summary>
/// Gets or sets the ImagesPathPrefix
/// </summary>
public string ImagesPathPrefix { get; set; }
/// <summary>
/// Gets or sets the ListPathPrefix
/// </summary>
public string ListPathPrefix { get; set; }
/// <summary>
/// Event fired when presets are loaded
/// </summary>
public event EventHandler PresetsLoaded;
/// <summary>
/// SetFileName method
/// </summary>
public void SetFileName(string path)
{
_filePath = ListPathPrefix + path;
Debug.LogMessage(LogEventLevel.Verbose, this, "Setting presets file path to {0}", _filePath);
LoadChannels();
}
/// <summary>
/// LoadChannels method
/// </summary>
public void LoadChannels()
{
try
{
_fileOps.Enter();
Debug.LogMessage(LogEventLevel.Verbose, this, "Loading presets from {0}", _filePath);
PresetsAreLoaded = false;
try
{
var pl = JsonConvert.DeserializeObject<PresetsList>(File.ReadToEnd(_filePath, Encoding.ASCII));
Name = pl.Name;
PresetsList = pl.Channels;
Debug.LogMessage(LogEventLevel.Verbose, this, "Loaded {0} presets", PresetsList.Count);
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Verbose, this,
"LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
_filePath, e.Message);
// Just save a default empty list
PresetsList = new List<PresetChannel>();
}
PresetsAreLoaded = true;
var handler = PresetsLoaded;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
finally
{
_fileOps.Leave();
}
}
/// <summary>
/// Dial method
/// </summary>
public void Dial(int presetNum)
{
if (presetNum <= PresetsList.Count)
{
Dial(PresetsList[presetNum - 1].Channel);
}
}
/// <summary>
/// Dial method
/// </summary>
public void Dial(string chanNum)
{
if (_dialIsRunning || !_initSuccess)
{
return;
}
if (_dialFunctions == null)
{
Debug.LogMessage(LogEventLevel.Debug, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
return;
}
_dialIsRunning = true;
CrestronInvoke.BeginInvoke(o =>
{
foreach (var c in chanNum.ToCharArray())
{
if (_dialFunctions.ContainsKey(c))
{
Pulse(_dialFunctions[c]);
}
CrestronEnvironment.Sleep(DigitSpacingMs);
}
if (_enterFunction != null)
{
Pulse(_enterFunction);
}
_dialIsRunning = false;
});
if (_setTopBox == null) return;
OnPresetRecalled(_setTopBox, chanNum);
}
/// <summary>
/// Dial method
/// </summary>
public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox)
{
if (presetNum <= PresetsList.Count)
{
Dial(PresetsList[presetNum - 1].Channel, setTopBox);
}
}
/// <summary>
/// Dial method
/// </summary>
public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
{
// 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},
@ -304,89 +60,245 @@ namespace PepperDash.Essentials.Core.Presets
{'0', setTopBox.Digit0},
{'-', setTopBox.Dash}
};
_enterFunction = setTopBox.KeypadEnter;
OnPresetRecalled(setTopBox, chanNum);
Dial(chanNum);
}
catch
{
Debug.LogMessage(LogEventLevel.Information, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
_dialFunctions = null;
return;
}
private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel)
_enterFunction = setTopBox.KeypadEnter;
}
public DevicePresetsModel(string key, string fileName) : base(key)
{
PulseTime = 150;
DigitSpacingMs = 150;
UseLocalImageStorage = true;
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
ImagesPathPrefix = @"/presets/images.zip/";
ListPathPrefix = @"/html/presets/lists/";
SetFileName(fileName);
_initSuccess = true;
}
public event PresetRecalledCallback PresetRecalled;
public event PresetsSavedCallback PresetsSaved;
public int PulseTime { get; set; }
public int DigitSpacingMs { get; set; }
public bool PresetsAreLoaded { get; private set; }
public List<PresetChannel> PresetsList { get; private set; }
public int Count
{
get { return PresetsList != null ? PresetsList.Count : 0; }
}
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)
{
_filePath = ListPathPrefix + path;
Debug.LogMessage(LogEventLevel.Verbose, this, "Setting presets file path to {0}", _filePath);
LoadChannels();
}
public void LoadChannels()
{
try
{
var handler = PresetRecalled;
_fileOps.Enter();
if (handler == null)
{
return;
}
handler(setTopBox, channel);
}
/// <summary>
/// UpdatePreset method
/// </summary>
public void UpdatePreset(int index, PresetChannel preset)
{
if (index >= PresetsList.Count)
{
return;
}
PresetsList[index] = preset;
SavePresets();
OnPresetsSaved();
}
/// <summary>
/// UpdatePresets method
/// </summary>
public void UpdatePresets(List<PresetChannel> presets)
{
PresetsList = presets;
SavePresets();
OnPresetsSaved();
}
private void SavePresets()
{
Debug.LogMessage(LogEventLevel.Verbose, this, "Loading presets from {0}", _filePath);
PresetsAreLoaded = false;
try
{
_fileOps.Enter();
var pl = new PresetsList {Channels = PresetsList, Name = Name};
var json = JsonConvert.SerializeObject(pl, Formatting.Indented);
var pl = JsonConvert.DeserializeObject<PresetsList>(File.ReadToEnd(_filePath, Encoding.ASCII));
Name = pl.Name;
PresetsList = pl.Channels;
using (var file = File.Open(_filePath, FileMode.Truncate))
{
file.Write(json, Encoding.UTF8);
}
Debug.LogMessage(LogEventLevel.Verbose, this, "Loaded {0} presets", PresetsList.Count);
}
finally
catch (Exception e)
{
_fileOps.Leave();
Debug.LogMessage(LogEventLevel.Verbose, this,
"LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
_filePath, e.Message);
// Just save a default empty list
PresetsList = new List<PresetChannel>();
}
PresetsAreLoaded = true;
var handler = PresetsLoaded;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
private void OnPresetsSaved()
finally
{
var handler = PresetsSaved;
if (handler == null) return;
handler(PresetsList);
}
private void Pulse(Action<bool> act)
{
act(true);
CrestronEnvironment.Sleep(PulseTime);
act(false);
_fileOps.Leave();
}
}
public void Dial(int presetNum)
{
if (presetNum <= PresetsList.Count)
{
Dial(PresetsList[presetNum - 1].Channel);
}
}
public void Dial(string chanNum)
{
if (_dialIsRunning || !_initSuccess)
{
return;
}
if (_dialFunctions == null)
{
Debug.LogMessage(LogEventLevel.Debug, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
return;
}
_dialIsRunning = true;
CrestronInvoke.BeginInvoke(o =>
{
foreach (var c in chanNum.ToCharArray())
{
if (_dialFunctions.ContainsKey(c))
{
Pulse(_dialFunctions[c]);
}
CrestronEnvironment.Sleep(DigitSpacingMs);
}
if (_enterFunction != null)
{
Pulse(_enterFunction);
}
_dialIsRunning = false;
});
if (_setTopBox == null) return;
OnPresetRecalled(_setTopBox, chanNum);
}
public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox)
{
if (presetNum <= PresetsList.Count)
{
Dial(PresetsList[presetNum - 1].Channel, setTopBox);
}
}
public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
{
_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}
};
_enterFunction = setTopBox.KeypadEnter;
OnPresetRecalled(setTopBox, chanNum);
Dial(chanNum);
}
private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel)
{
var handler = PresetRecalled;
if (handler == null)
{
return;
}
handler(setTopBox, channel);
}
public void UpdatePreset(int index, PresetChannel preset)
{
if (index >= PresetsList.Count)
{
return;
}
PresetsList[index] = preset;
SavePresets();
OnPresetsSaved();
}
public void UpdatePresets(List<PresetChannel> presets)
{
PresetsList = presets;
SavePresets();
OnPresetsSaved();
}
private void SavePresets()
{
try
{
_fileOps.Enter();
var pl = new PresetsList {Channels = PresetsList, Name = Name};
var json = JsonConvert.SerializeObject(pl, Formatting.Indented);
using (var file = File.Open(_filePath, FileMode.Truncate))
{
file.Write(json, Encoding.UTF8);
}
}
finally
{
_fileOps.Leave();
}
}
private void OnPresetsSaved()
{
var handler = PresetsSaved;
if (handler == null) return;
handler(PresetsList);
}
private void Pulse(Action<bool> act)
{
act(true);
CrestronEnvironment.Sleep(PulseTime);
act(false);
}
}

View file

@ -6,88 +6,87 @@ using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials.Core.Presets
namespace PepperDash.Essentials.Core.Presets;
/// <summary>
/// Represents a DevicePresetsView
/// </summary>
public class DevicePresetsView
{
/// <summary>
/// Represents a DevicePresetsView
/// Gets or sets the ShowNumbers
/// </summary>
public class DevicePresetsView
public bool ShowNumbers { get; set; }
/// <summary>
/// Gets or sets the ShowName
/// </summary>
public bool ShowName { get; set; }
/// <summary>
/// Gets or sets the ShowIcon
/// </summary>
public bool ShowIcon { get; set; }
/// <summary>
/// Gets the SubpageReferenceList
/// </summary>
public SubpageReferenceList SRL { get; private set; }
/// <summary>
/// Gets the DevicePresetsModel
/// </summary>
public DevicePresetsModel Model { get; private set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="tl">trilst</param>
/// <param name="model">device presets model</param>
/// <exception cref="ArgumentNullException"></exception>
public DevicePresetsView(BasicTriListWithSmartObject tl, DevicePresetsModel model)
{
/// <summary>
/// Gets or sets the ShowNumbers
/// </summary>
public bool ShowNumbers { get; set; }
/// <summary>
/// Gets or sets the ShowName
/// </summary>
public bool ShowName { get; set; }
/// <summary>
/// Gets or sets the ShowIcon
/// </summary>
public bool ShowIcon { get; set; }
/// <summary>
/// Gets or sets the SRL
/// </summary>
public SubpageReferenceList SRL { get; private set; }
/// <summary>
/// Gets or sets the Model
/// </summary>
public DevicePresetsModel Model { get; private set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="tl">trilst</param>
/// <param name="model">device presets model</param>
/// <exception cref="ArgumentNullException"></exception>
public DevicePresetsView(BasicTriListWithSmartObject tl, DevicePresetsModel model)
if (model == null)
{
if (model == null)
throw new ArgumentNullException("model", "DevicePresetsView Cannot be instantiated with null model");
}
ShowIcon = true;
ShowName = true;
Model = model;
SRL = new SubpageReferenceList(tl, 10012, 3, 0, 4);
Model.PresetsLoaded += new EventHandler(Model_PresetsLoaded);
}
/// <summary>
/// Attach method
/// </summary>
public void Attach()
{
if (Model.PresetsAreLoaded)
{
uint index = 1;
foreach (var p in Model.PresetsList)
{
throw new ArgumentNullException("model", "DevicePresetsView Cannot be instantiated with null model");
SRL.AddItem(new PresetsListSubpageReferenceListItem(p, index, SRL, this));
index++;
}
ShowIcon = true;
ShowName = true;
Model = model;
SRL = new SubpageReferenceList(tl, 10012, 3, 0, 4);
Model.PresetsLoaded += new EventHandler(Model_PresetsLoaded);
}
/// <summary>
/// Attach method
/// </summary>
public void Attach()
{
if (Model.PresetsAreLoaded)
{
uint index = 1;
foreach (var p in Model.PresetsList)
{
SRL.AddItem(new PresetsListSubpageReferenceListItem(p, index, SRL, this));
index++;
}
SRL.Count = (ushort)Model.PresetsList.Count;
}
}
/// <summary>
/// Detach method
/// </summary>
public void Detach()
{
SRL.Clear();
}
void Model_PresetsLoaded(object sender, EventArgs e)
{
Detach();
Attach();
SRL.Count = (ushort)Model.PresetsList.Count;
}
}
/// <summary>
/// Detach method
/// </summary>
public void Detach()
{
SRL.Clear();
}
void Model_PresetsLoaded(object sender, EventArgs e)
{
Detach();
Attach();
}
}

View file

@ -7,48 +7,47 @@ using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core.Presets
namespace PepperDash.Essentials.Core.Presets;
/// <summary>
/// Represents a PresetChannel
/// </summary>
public class PresetChannel
{
/// <summary>
/// Represents a PresetChannel
/// </summary>
public class PresetChannel
{
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty(Required = Required.Always,PropertyName = "name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the IconUrl
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "iconUrl")]
public string IconUrl { get; set; }
/// <summary>
/// Gets or sets the Channel
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "channel")]
public string Channel { get; set; }
}
/// <summary>
/// Represents a PresetsList
/// Gets or sets the Name
/// </summary>
public class PresetsList
{
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty(Required=Required.Always,PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(Required = Required.Always, PropertyName = "name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the Channels
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "channels")]
public List<PresetChannel> Channels { get; set; }
}
/// <summary>
/// Gets or sets the IconUrl
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "iconUrl")]
public string IconUrl { get; set; }
/// <summary>
/// Gets or sets the Channel
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "channel")]
public string Channel { get; set; }
}
/// <summary>
/// Represents a PresetsList
/// </summary>
public class PresetsList
{
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the Channels
/// </summary>
[JsonProperty(Required = Required.Always, PropertyName = "channels")]
public List<PresetChannel> Channels { get; set; }
}

View file

@ -10,11 +10,8 @@ using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.Core.Presets
{
/// <summary>
/// Represents a PresetsListSubpageReferenceListItem
/// </summary>
namespace PepperDash.Essentials.Core.Presets;
public class PresetsListSubpageReferenceListItem : SubpageReferenceListItem
{
DevicePresetsView View;
@ -64,5 +61,4 @@ namespace PepperDash.Essentials.Core.Presets
var icon = View.ShowIcon ? url : "";
Owner.StringInputSig(Index, 3).StringValue = icon;
}
}
}
}