mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-08-31 19:08:29 +00:00
Improve logic to check for MPC3Basic type using pattern matching. Update debug and error messages to report actual device type. Clarify conditional structure for better readability.
331 lines
No EOL
13 KiB
C#
331 lines
No EOL
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using Crestron.SimplSharpPro;
|
|
using PepperDash.Core;
|
|
using PepperDash.Core.Logging;
|
|
using Serilog.Events;
|
|
|
|
namespace PepperDash.Essentials.Core.Touchpanels
|
|
{
|
|
/// <summary>
|
|
/// A wrapper class for the touchpanel portion of an MPC4 class process to allow for configurable
|
|
/// behavior of the keypad buttons
|
|
/// </summary>
|
|
public class Mpc4TouchpanelController : Device
|
|
{
|
|
readonly MPC3Basic _touchpanel;
|
|
|
|
readonly Dictionary<string, KeypadButton> _buttons;
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="key">device key</param>
|
|
/// <param name="name">device name</param>
|
|
/// <param name="processor">control system processor</param>
|
|
/// <param name="buttons">dictionary of keypad buttons</param>
|
|
public Mpc4TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary<string, KeypadButton> buttons)
|
|
: base(key, name)
|
|
{
|
|
if (processor.MPC4x102TouchscreenSlot != null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, this, "Using MPC4x102TouchscreenSlot");
|
|
_touchpanel = processor.MPC4x102TouchscreenSlot;
|
|
}
|
|
else if (processor.MPC4x201TouchscreenSlot != null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, this, "Using MPC4x201TouchscreenSlot");
|
|
_touchpanel = processor.MPC4x201TouchscreenSlot;
|
|
}
|
|
else if (processor.MPC4x301TouchscreenSlot != null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, this, "Using MPC4x301TouchscreenSlot");
|
|
_touchpanel = processor.MPC4x301TouchscreenSlot;
|
|
}
|
|
else if (processor.MPC4x302TouchscreenSlot != null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, this, "Using MPC4x302TouchscreenSlot");
|
|
_touchpanel = processor.MPC4x302TouchscreenSlot;
|
|
}
|
|
else if (processor.ControllerTouchScreenSlotDevice != null && processor.ControllerTouchScreenSlotDevice is MPC3Basic mpc)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Information, this, "Using ControllerTouchScreenSlotDevice:{0}", processor.ControllerTouchScreenSlotDevice.GetType().Name);
|
|
_touchpanel = mpc;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Error, this, "Failed to find MPC4 Touchpanel Controller with key {0}, check configuration, processor is type: {1}", key, processor.ControllerTouchScreenSlotDevice?.GetType().Name ?? "unknown");
|
|
return;
|
|
}
|
|
|
|
if (_touchpanel.Registerable)
|
|
{
|
|
var registrationResponse = _touchpanel.Register();
|
|
Debug.LogMessage(LogEventLevel.Information, this, "touchpanel registration response: {0}", registrationResponse);
|
|
}
|
|
|
|
_touchpanel.BaseEvent += Touchpanel_BaseEvent;
|
|
_touchpanel.ButtonStateChange += Touchpanel_ButtonStateChange;
|
|
_touchpanel.PanelStateChange += Touchpanel_PanelStateChange;
|
|
|
|
_buttons = buttons;
|
|
if (_buttons == null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this,
|
|
"Button properties are null, failed to setup MPC4 Touch Controller, check configuration");
|
|
return;
|
|
}
|
|
|
|
AddPostActivationAction(() =>
|
|
{
|
|
foreach (var button in _buttons)
|
|
{
|
|
var buttonKey = button.Key.ToLower();
|
|
var buttonConfig = button.Value;
|
|
|
|
InitializeButton(buttonKey, buttonConfig);
|
|
InitializeButtonFeedback(buttonKey, buttonConfig);
|
|
}
|
|
|
|
ListButtons();
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enables/disables buttons based on event type configuration
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="config"></param>
|
|
public void InitializeButton(string key, KeypadButton config)
|
|
{
|
|
if (config == null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' config is null, unable to initialize", key);
|
|
return;
|
|
}
|
|
|
|
TryParseInt(key, out int buttonNumber);
|
|
|
|
var buttonEventTypes = config.EventTypes;
|
|
BoolOutputSig enabledFb = null;
|
|
BoolOutputSig disabledFb = null;
|
|
|
|
switch (key)
|
|
{
|
|
case ("power"):
|
|
{
|
|
if (buttonEventTypes == null || buttonEventTypes.Keys == null)
|
|
_touchpanel.DisablePowerButton();
|
|
else
|
|
_touchpanel.EnablePowerButton();
|
|
|
|
|
|
enabledFb = _touchpanel.PowerButtonEnabledFeedBack;
|
|
disabledFb = _touchpanel.PowerButtonDisabledFeedBack;
|
|
|
|
break;
|
|
}
|
|
case ("mute"):
|
|
{
|
|
if (buttonEventTypes == null || buttonEventTypes.Keys == null)
|
|
_touchpanel.DisableMuteButton();
|
|
else
|
|
_touchpanel.EnableMuteButton();
|
|
|
|
|
|
enabledFb = _touchpanel.MuteButtonEnabledFeedBack;
|
|
disabledFb = _touchpanel.MuteButtonDisabledFeedBack;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
if (buttonNumber == 0 || buttonNumber > 9)
|
|
break;
|
|
|
|
if (buttonEventTypes == null || buttonEventTypes.Keys == null)
|
|
_touchpanel.DisableNumericalButton((uint)buttonNumber);
|
|
else
|
|
_touchpanel.EnableNumericalButton((uint)buttonNumber);
|
|
|
|
|
|
if (_touchpanel.NumericalButtonEnabledFeedBack != null)
|
|
enabledFb = _touchpanel.NumericalButtonEnabledFeedBack[(uint)buttonNumber];
|
|
|
|
if (_touchpanel.NumericalButtonDisabledFeedBack != null)
|
|
disabledFb = _touchpanel.NumericalButtonDisabledFeedBack[(uint)buttonNumber];
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
Debug.LogMessage(LogEventLevel.Information, this, "InitializeButton: key-'{0}' enabledFb-'{1}', disabledFb-'{2}'",
|
|
key, enabledFb ?? (object)"null", disabledFb ?? (object)"null");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Links button feedback if configured
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="config"></param>
|
|
public void InitializeButtonFeedback(string key, KeypadButton config)
|
|
{
|
|
if (config == null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' config is null, skipping.", key);
|
|
return;
|
|
}
|
|
|
|
TryParseInt(key, out int buttonNumber);
|
|
|
|
// Link up the button feedbacks to the specified device feedback
|
|
var buttonFeedback = config.Feedback;
|
|
if (buttonFeedback == null || string.IsNullOrEmpty(buttonFeedback.DeviceKey))
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedback not configured, skipping.",
|
|
key);
|
|
return;
|
|
}
|
|
|
|
Feedback deviceFeedback;
|
|
|
|
try
|
|
{
|
|
if (!(DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) is Device device))
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedback deviceKey '{1}' not found.",
|
|
key, buttonFeedback.DeviceKey);
|
|
return;
|
|
}
|
|
|
|
deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName);
|
|
if (deviceFeedback == null)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "Button '{0}' feedbackName property '{1}' not found.",
|
|
key, buttonFeedback.FeedbackName);
|
|
return;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') Exception Message: {0}",
|
|
ex.Message, key, buttonFeedback.DeviceKey);
|
|
Debug.LogMessage(LogEventLevel.Verbose, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') Exception StackTrace: {0}",
|
|
ex.StackTrace, key, buttonFeedback.DeviceKey);
|
|
if (ex.InnerException != null) Debug.LogMessage(LogEventLevel.Verbose, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') InnerException: {0}",
|
|
ex.InnerException, key, buttonFeedback.DeviceKey);
|
|
|
|
return;
|
|
}
|
|
|
|
var boolFeedback = deviceFeedback as BoolFeedback;
|
|
|
|
switch (key)
|
|
{
|
|
case ("power"):
|
|
{
|
|
boolFeedback?.LinkCrestronFeedback(_touchpanel.FeedbackPower);
|
|
break;
|
|
}
|
|
case ("volumeup"):
|
|
case ("volumedown"):
|
|
case ("volumefeedback"):
|
|
{
|
|
if (deviceFeedback is IntFeedback intFeedback)
|
|
{
|
|
var volumeFeedback = intFeedback;
|
|
volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph);
|
|
}
|
|
break;
|
|
}
|
|
case ("mute"):
|
|
{
|
|
boolFeedback?.LinkCrestronFeedback(_touchpanel.FeedbackMute);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
boolFeedback?.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Try parse int helper method
|
|
/// </summary>
|
|
/// <param name="str"></param>
|
|
/// <param name="result"></param>
|
|
/// <returns></returns>
|
|
public bool TryParseInt(string str, out int result)
|
|
{
|
|
try
|
|
{
|
|
result = int.Parse(str);
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
result = 0;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void Touchpanel_BaseEvent(GenericBase device, BaseEventArgs args)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "BaseEvent: eventId-'{0}', index-'{1}'", args.EventId, args.Index);
|
|
}
|
|
|
|
private void Touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "ButtonStateChange: buttonNumber-'{0}' buttonName-'{1}', buttonState-'{2}'", args.Button.Number, args.Button.Name, args.NewButtonState);
|
|
var type = args.NewButtonState.ToString();
|
|
|
|
if (_buttons.ContainsKey(args.Button.Number.ToString(CultureInfo.InvariantCulture)))
|
|
{
|
|
Press(args.Button.Number.ToString(CultureInfo.InvariantCulture), type);
|
|
}
|
|
else if (_buttons.ContainsKey(args.Button.Name.ToString()))
|
|
{
|
|
Press(args.Button.Name.ToString(), type);
|
|
}
|
|
}
|
|
|
|
private void Touchpanel_PanelStateChange(GenericBase device, BaseEventArgs args)
|
|
{
|
|
Debug.LogMessage(LogEventLevel.Debug, this, "PanelStateChange: eventId-'{0}', index-'{1}'", args.EventId, args.Index);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the function associated with this button/type. One of the following strings:
|
|
/// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased
|
|
/// </summary>
|
|
/// <param name="buttonKey"></param>
|
|
/// <param name="type"></param>
|
|
public void Press(string buttonKey, string type)
|
|
{
|
|
this.LogVerbose("Press: buttonKey-'{buttonKey}', type-'{type}'", buttonKey, type);
|
|
|
|
if (!_buttons.ContainsKey(buttonKey)) return;
|
|
|
|
var button = _buttons[buttonKey];
|
|
if (!button.EventTypes.ContainsKey(type)) return;
|
|
|
|
foreach (var eventType in button.EventTypes[type]) DeviceJsonApi.DoDeviceAction(eventType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// ListButtons method
|
|
/// </summary>
|
|
public void ListButtons()
|
|
{
|
|
this.LogVerbose("MPC4 Controller {0} - Available Buttons", Key);
|
|
|
|
foreach (var button in _buttons)
|
|
{
|
|
this.LogVerbose("Key: {key}", button.Key);
|
|
}
|
|
}
|
|
}
|
|
} |