mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
refactor: rearrange and add solution for 4-series
This commit is contained in:
@@ -0,0 +1,379 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.DSP
|
||||
{
|
||||
public interface IBiampTesiraDspLevelControl : IBasicVolumeWithFeedback
|
||||
{
|
||||
/// <summary>
|
||||
/// In BiAmp: Instance Tag, QSC: Named Control, Polycom:
|
||||
/// </summary>
|
||||
string ControlPointTag { get; }
|
||||
int Index1 { get; }
|
||||
int Index2 { get; }
|
||||
bool HasMute { get; }
|
||||
bool HasLevel { get; }
|
||||
bool AutomaticUnmuteOnVolumeUp { get; }
|
||||
}
|
||||
|
||||
public class TesiraForteLevelControl : TesiraForteControlPoint, IBiampTesiraDspLevelControl, IKeyed
|
||||
{
|
||||
bool _IsMuted;
|
||||
ushort _VolumeLevel;
|
||||
|
||||
public BoolFeedback MuteFeedback { get; private set; }
|
||||
|
||||
public IntFeedback VolumeLevelFeedback { get; private set; }
|
||||
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
public string ControlPointTag { get { return base.InstanceTag; } }
|
||||
|
||||
/// <summary>
|
||||
/// Used for to identify level subscription values
|
||||
/// </summary>
|
||||
public string LevelCustomName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used for to identify mute subscription values
|
||||
/// </summary>
|
||||
public string MuteCustomName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum fader level
|
||||
/// </summary>
|
||||
double MinLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum fader level
|
||||
/// </summary>
|
||||
double MaxLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a valid subscription string has been recieved for all subscriptions
|
||||
/// </summary>
|
||||
public bool IsSubsribed
|
||||
{
|
||||
get
|
||||
{
|
||||
bool isSubscribed = false;
|
||||
|
||||
if (HasMute && MuteIsSubscribed)
|
||||
isSubscribed = true;
|
||||
|
||||
if (HasLevel && LevelIsSubscribed)
|
||||
isSubscribed = true;
|
||||
|
||||
return isSubscribed;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutomaticUnmuteOnVolumeUp { get; private set; }
|
||||
|
||||
public bool HasMute { get; private set; }
|
||||
|
||||
public bool HasLevel { get; private set; }
|
||||
|
||||
bool MuteIsSubscribed;
|
||||
|
||||
bool LevelIsSubscribed;
|
||||
|
||||
//public TesiraForteLevelControl(string label, string id, int index1, int index2, bool hasMute, bool hasLevel, BiampTesiraForteDsp parent)
|
||||
// : base(id, index1, index2, parent)
|
||||
//{
|
||||
// Initialize(label, hasMute, hasLevel);
|
||||
//}
|
||||
|
||||
public TesiraForteLevelControl(string key, BiampTesiraForteLevelControlBlockConfig config, BiampTesiraForteDsp parent)
|
||||
: base(config.InstanceTag, config.Index1, config.Index2, parent)
|
||||
{
|
||||
Initialize(key, config.Label, config.HasMute, config.HasLevel);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this attribute based on config values and generates subscriptions commands and adds commands to the parent's queue.
|
||||
/// </summary>
|
||||
public void Initialize(string key, string label, bool hasMute, bool hasLevel)
|
||||
{
|
||||
Key = string.Format("{0}--{1}", Parent.Key, key);
|
||||
|
||||
DeviceManager.AddDevice(this);
|
||||
|
||||
Debug.Console(2, this, "Adding LevelControl '{0}'", Key);
|
||||
|
||||
this.IsSubscribed = false;
|
||||
|
||||
MuteFeedback = new BoolFeedback(() => _IsMuted);
|
||||
|
||||
VolumeLevelFeedback = new IntFeedback(() => _VolumeLevel);
|
||||
|
||||
HasMute = hasMute;
|
||||
HasLevel = hasLevel;
|
||||
}
|
||||
|
||||
public void Subscribe()
|
||||
{
|
||||
// Do subscriptions and blah blah
|
||||
|
||||
// Subscribe to mute
|
||||
if (this.HasMute)
|
||||
{
|
||||
MuteCustomName = string.Format("{0}~mute{1}", this.InstanceTag, this.Index1);
|
||||
|
||||
SendSubscriptionCommand(MuteCustomName, "mute", 500);
|
||||
}
|
||||
|
||||
// Subscribe to level
|
||||
if (this.HasLevel)
|
||||
{
|
||||
LevelCustomName = string.Format("{0}~level{1}", this.InstanceTag, this.Index1);
|
||||
|
||||
SendSubscriptionCommand(LevelCustomName, "level", 250);
|
||||
|
||||
SendFullCommand("get", "minLevel", null);
|
||||
|
||||
SendFullCommand("get", "maxLevel", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parses the response from the DspBase
|
||||
/// </summary>
|
||||
/// <param name="customName"></param>
|
||||
/// <param name="value"></param>
|
||||
public void ParseSubscriptionMessage(string customName, string value)
|
||||
{
|
||||
|
||||
// Check for valid subscription response
|
||||
|
||||
if (this.HasMute && customName == MuteCustomName)
|
||||
{
|
||||
//if (value.IndexOf("+OK") > -1)
|
||||
//{
|
||||
// int pointer = value.IndexOf(" +OK");
|
||||
|
||||
// MuteIsSubscribed = true;
|
||||
|
||||
// // Removes the +OK
|
||||
// value = value.Substring(0, value.Length - (value.Length - (pointer - 1)));
|
||||
//}
|
||||
|
||||
if (value.IndexOf("true") > -1)
|
||||
{
|
||||
_IsMuted = true;
|
||||
MuteIsSubscribed = true;
|
||||
|
||||
}
|
||||
else if (value.IndexOf("false") > -1)
|
||||
{
|
||||
_IsMuted = false;
|
||||
MuteIsSubscribed = true;
|
||||
}
|
||||
|
||||
MuteFeedback.FireUpdate();
|
||||
}
|
||||
else if (this.HasLevel && customName == LevelCustomName)
|
||||
{
|
||||
//if (value.IndexOf("+OK") > -1)
|
||||
//{
|
||||
// int pointer = value.IndexOf(" +OK");
|
||||
|
||||
// LevelIsSubscribed = true;
|
||||
|
||||
//}
|
||||
|
||||
var _value = Double.Parse(value);
|
||||
|
||||
_VolumeLevel = (ushort)Scale(_value, MinLevel, MaxLevel, 0, 65535);
|
||||
|
||||
LevelIsSubscribed = true;
|
||||
|
||||
VolumeLevelFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a non subscription response
|
||||
/// </summary>
|
||||
/// <param name="attributeCode">The attribute code of the command</param>
|
||||
/// <param name="message">The message to parse</param>
|
||||
public override void ParseGetMessage(string attributeCode, string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse an "+OK" message
|
||||
string pattern = @"\+OK ""value"":(.*)";
|
||||
|
||||
Match match = Regex.Match(message, pattern);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
|
||||
string value = match.Groups[1].Value;
|
||||
|
||||
Debug.Console(1, this, "Response: '{0}' Value: '{1}'", attributeCode, value);
|
||||
|
||||
if (message.IndexOf("\"value\":") > -1)
|
||||
{
|
||||
switch (attributeCode)
|
||||
{
|
||||
case "minLevel":
|
||||
{
|
||||
MinLevel = Double.Parse(value);
|
||||
|
||||
Debug.Console(1, this, "MinLevel is '{0}'", MinLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
case "maxLevel":
|
||||
{
|
||||
MaxLevel = Double.Parse(value);
|
||||
|
||||
Debug.Console(1, this, "MaxLevel is '{0}'", MaxLevel);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(2, "Response does not match expected attribute codes: '{0}'", message);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Unable to parse message: '{0}'\n{1}", message, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns the mute off
|
||||
/// </summary>
|
||||
public void MuteOff()
|
||||
{
|
||||
SendFullCommand("set", "mute", "false");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns the mute on
|
||||
/// </summary>
|
||||
public void MuteOn()
|
||||
{
|
||||
SendFullCommand("set", "mute", "true");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume to a specified level
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
public void SetVolume(ushort level)
|
||||
{
|
||||
Debug.Console(1, this, "volume: {0}", level);
|
||||
// Unmute volume if new level is higher than existing
|
||||
if (level > _VolumeLevel && AutomaticUnmuteOnVolumeUp)
|
||||
if(_IsMuted)
|
||||
MuteOff();
|
||||
|
||||
double volumeLevel = Scale(level, 0, 65535, MinLevel, MaxLevel);
|
||||
|
||||
SendFullCommand("set", "level", string.Format("{0:0.000000}", volumeLevel));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles mute status
|
||||
/// </summary>
|
||||
public void MuteToggle()
|
||||
{
|
||||
SendFullCommand("toggle", "mute", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrements volume level
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
SendFullCommand("decrement", "level", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increments volume level
|
||||
/// </summary>
|
||||
/// <param name="pressRelease"></param>
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
SendFullCommand("increment", "level", "");
|
||||
|
||||
if (AutomaticUnmuteOnVolumeUp)
|
||||
if (!_IsMuted)
|
||||
MuteOff();
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Scales the input from the input range to the output range
|
||||
///// </summary>
|
||||
///// <param name="input"></param>
|
||||
///// <param name="inMin"></param>
|
||||
///// <param name="inMax"></param>
|
||||
///// <param name="outMin"></param>
|
||||
///// <param name="outMax"></param>
|
||||
///// <returns></returns>
|
||||
//int Scale(int input, int inMin, int inMax, int outMin, int outMax)
|
||||
//{
|
||||
// Debug.Console(1, this, "Scaling (int) input '{0}' with min '{1}'/max '{2}' to output range min '{3}'/max '{4}'", input, inMin, inMax, outMin, outMax);
|
||||
|
||||
// int inputRange = inMax - inMin;
|
||||
|
||||
// int outputRange = outMax - outMin;
|
||||
|
||||
// var output = (((input-inMin) * outputRange) / inputRange ) - outMin;
|
||||
|
||||
// Debug.Console(1, this, "Scaled output '{0}'", output);
|
||||
|
||||
// return output;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Scales the input from the input range to the output range
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="inMin"></param>
|
||||
/// <param name="inMax"></param>
|
||||
/// <param name="outMin"></param>
|
||||
/// <param name="outMax"></param>
|
||||
/// <returns></returns>
|
||||
double Scale(double input, double inMin, double inMax, double outMin, double outMax)
|
||||
{
|
||||
Debug.Console(1, this, "Scaling (double) input '{0}' with min '{1}'/max '{2}' to output range min '{3}'/max '{4}'",input ,inMin ,inMax ,outMin, outMax);
|
||||
|
||||
double inputRange = inMax - inMin;
|
||||
|
||||
if (inputRange <= 0)
|
||||
{
|
||||
throw new ArithmeticException(string.Format("Invalid Input Range '{0}' for Scaling. Min '{1}' Max '{2}'.", inputRange, inMin, inMax));
|
||||
}
|
||||
|
||||
double outputRange = outMax - outMin;
|
||||
|
||||
var output = (((input - inMin) * outputRange) / inputRange) + outMin;
|
||||
|
||||
Debug.Console(1, this, "Scaled output '{0}'", output);
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user