mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-08-31 19:08:29 +00:00
Compare commits
4 commits
main
...
v2.40.0-ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c56623641 | ||
|
|
31fd665594 | ||
|
|
d713d65c7a | ||
|
|
f5d6a076ad |
2 changed files with 342 additions and 0 deletions
323
src/PepperDash.Essentials.Core/Touchpanels/Mpc4Touchpanel.cs
Normal file
323
src/PepperDash.Essentials.Core/Touchpanels/Mpc4Touchpanel.cs
Normal file
|
|
@ -0,0 +1,323 @@
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
_touchpanel = processor.MPC4x102TouchscreenSlot;
|
||||||
|
}
|
||||||
|
else if (processor.MPC4x201TouchscreenSlot != null)
|
||||||
|
{
|
||||||
|
_touchpanel = processor.MPC4x201TouchscreenSlot;
|
||||||
|
}
|
||||||
|
else if (processor.MPC4x301TouchscreenSlot != null)
|
||||||
|
{
|
||||||
|
_touchpanel = processor.MPC4x301TouchscreenSlot;
|
||||||
|
}
|
||||||
|
else if (processor.MPC4x302TouchscreenSlot != null)
|
||||||
|
{
|
||||||
|
_touchpanel = processor.MPC4x302TouchscreenSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_touchpanel == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Error, this, "Failed to construct MPC4 Touchpanel Controller with key {0}, check configuration, processor is type: {1}", key, processor.ControllerTouchScreenSlotDevice?.GetType().FullName ?? "null");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -436,6 +436,25 @@ namespace PepperDash.Essentials
|
||||||
"WARNING: Config file defines processor type as '{deviceType:l}' but actual processor is '{processorType:l}'! Some ports may not be available",
|
"WARNING: Config file defines processor type as '{deviceType:l}' but actual processor is '{processorType:l}'! Some ports may not be available",
|
||||||
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
|
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
|
||||||
|
|
||||||
|
// Check if the processor is an MPC4 model
|
||||||
|
if (prompt.IndexOf("mpc4", StringComparison.OrdinalIgnoreCase) > -1)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, "MPC4 processor type detected. Adding Mpc4TouchpanelController.");
|
||||||
|
|
||||||
|
var butToken = devConf.Properties["buttons"];
|
||||||
|
if (butToken == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Warning,
|
||||||
|
"Error: Unable to deserialize buttons collection for device: {deviceKey}", devConf.Key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttons = Newtonsoft.Json.JsonConvert.DeserializeObject<System.Collections.Generic.Dictionary<string, Core.Touchpanels.KeypadButton>>(butToken.ToString());
|
||||||
|
var tpController = new Core.Touchpanels.Mpc4TouchpanelController(
|
||||||
|
string.Format("{0}-keypadButtons", devConf.Key), devConf.Name, Global.ControlSystem, buttons);
|
||||||
|
|
||||||
|
DeviceManager.AddDevice(tpController);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue