mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-08-31 19:08:29 +00:00
feat: enhance audio codec phonebook functionality and messaging integration
This commit is contained in:
parent
c8faa19835
commit
0098673a5e
4 changed files with 135 additions and 67 deletions
|
|
@ -281,84 +281,92 @@ public class DeviceJsonApi
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static object FindObjectOnPath(string deviceObjectPath)
|
public static object FindObjectOnPath(string deviceObjectPath)
|
||||||
{
|
{
|
||||||
var path = deviceObjectPath.Split('.');
|
try
|
||||||
|
|
||||||
var dev = DeviceManager.GetDeviceForKey(path[0]);
|
|
||||||
if (dev == null)
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Device {0} not found", path[0]);
|
var path = deviceObjectPath.Split('.');
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop through any dotted properties
|
var dev = DeviceManager.GetDeviceForKey(path[0]);
|
||||||
object obj = dev;
|
if (dev == null)
|
||||||
if (path.Length > 1)
|
|
||||||
{
|
|
||||||
for (int i = 1; i < path.Length; i++)
|
|
||||||
{
|
{
|
||||||
var objName = path[i];
|
Debug.LogMessage(LogEventLevel.Information, "Device {0} not found", path[0]);
|
||||||
string indexStr = null;
|
return null;
|
||||||
var indexOpen = objName.IndexOf('[');
|
}
|
||||||
if (indexOpen != -1)
|
|
||||||
{
|
|
||||||
var indexClose = objName.IndexOf(']');
|
|
||||||
if (indexClose == -1)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, dev, "ERROR Unmatched index brackets");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Get the index and strip quotes if any
|
|
||||||
indexStr = objName.Substring(indexOpen + 1, indexClose - indexOpen - 1).Replace("\"", "");
|
|
||||||
objName = objName.Substring(0, indexOpen);
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, dev, " Checking for collection '{0}', index '{1}'", objName, indexStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type oType = obj.GetType();
|
// loop through any dotted properties
|
||||||
var prop = oType.GetProperty(objName);
|
object obj = dev;
|
||||||
if (prop == null)
|
if (path.Length > 1)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < path.Length; i++)
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, dev, "Property {0} not found on {1}", objName, path[i - 1]);
|
var objName = path[i];
|
||||||
return null;
|
string indexStr = null;
|
||||||
}
|
var indexOpen = objName.IndexOf('[');
|
||||||
// if there's an index, try to get the property
|
if (indexOpen != -1)
|
||||||
if (indexStr != null)
|
|
||||||
{
|
|
||||||
if (!typeof(ICollection).IsAssignableFrom(prop.PropertyType))
|
|
||||||
{
|
{
|
||||||
Debug.LogMessage(LogEventLevel.Information, dev, "Property {0} is not collection", objName);
|
var indexClose = objName.IndexOf(']');
|
||||||
return null;
|
if (indexClose == -1)
|
||||||
}
|
|
||||||
var collection = prop.GetValue(obj, null) as ICollection;
|
|
||||||
// Get the indexed items "property"
|
|
||||||
var indexedPropInfo = prop.PropertyType.GetProperty("Item");
|
|
||||||
// These are the parameters for the indexing. Only care about one
|
|
||||||
var indexParams = indexedPropInfo.GetIndexParameters();
|
|
||||||
if (indexParams.Length > 0)
|
|
||||||
{
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, " Indexed, param type: {0}", indexParams[0].ParameterType.Name);
|
|
||||||
var properParam = Convert.ChangeType(indexStr, indexParams[0].ParameterType,
|
|
||||||
System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
obj = indexedPropInfo.GetValue(collection, new object[] { properParam });
|
Debug.LogMessage(LogEventLevel.Information, dev, "ERROR Unmatched index brackets");
|
||||||
}
|
|
||||||
// if the index is bad, catch it here.
|
|
||||||
catch (TargetInvocationException e)
|
|
||||||
{
|
|
||||||
if (e.InnerException is ArgumentOutOfRangeException)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, " Index Out of range");
|
|
||||||
else if (e.InnerException is KeyNotFoundException)
|
|
||||||
Debug.LogMessage(LogEventLevel.Information, " Key not found");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// Get the index and strip quotes if any
|
||||||
|
indexStr = objName.Substring(indexOpen + 1, indexClose - indexOpen - 1).Replace("\"", "");
|
||||||
|
objName = objName.Substring(0, indexOpen);
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, dev, " Checking for collection '{0}', index '{1}'", objName, indexStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type oType = obj.GetType();
|
||||||
|
var prop = oType.GetProperty(objName);
|
||||||
|
if (prop == null)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, dev, "Property {0} not found on {1}", objName, path[i - 1]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// if there's an index, try to get the property
|
||||||
|
if (indexStr != null)
|
||||||
|
{
|
||||||
|
if (!typeof(ICollection).IsAssignableFrom(prop.PropertyType))
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, dev, "Property {0} is not collection", objName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var collection = prop.GetValue(obj, null) as ICollection;
|
||||||
|
// Get the indexed items "property"
|
||||||
|
var indexedPropInfo = prop.PropertyType.GetProperty("Item");
|
||||||
|
// These are the parameters for the indexing. Only care about one
|
||||||
|
var indexParams = indexedPropInfo.GetIndexParameters();
|
||||||
|
if (indexParams.Length > 0)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, " Indexed, param type: {0}", indexParams[0].ParameterType.Name);
|
||||||
|
var properParam = Convert.ChangeType(indexStr, indexParams[0].ParameterType,
|
||||||
|
System.Globalization.CultureInfo.InvariantCulture);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
obj = indexedPropInfo.GetValue(collection, new object[] { properParam });
|
||||||
|
}
|
||||||
|
// if the index is bad, catch it here.
|
||||||
|
catch (TargetInvocationException e)
|
||||||
|
{
|
||||||
|
if (e.InnerException is ArgumentOutOfRangeException)
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, " Index Out of range");
|
||||||
|
else if (e.InnerException is KeyNotFoundException)
|
||||||
|
Debug.LogMessage(LogEventLevel.Information, " Key not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
obj = prop.GetValue(obj, null);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
obj = prop.GetValue(obj, null);
|
|
||||||
}
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Error, e, "Error finding object on path {deviceObjectPath}", deviceObjectPath);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
@ -8,16 +9,35 @@ using Serilog.Events;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.AudioCodec;
|
namespace PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
|
|
||||||
public class MockAC : AudioCodecBase
|
public class MockAC : AudioCodecBase, IAudioCodecPhonebook
|
||||||
{
|
{
|
||||||
|
public event EventHandler<PhonebookListChangedEventArgs> ListChanged;
|
||||||
|
|
||||||
|
public List<CodecPhonebookEntry> PhonebookEntries { get; }
|
||||||
|
|
||||||
public MockAC(string key, string name, MockAcPropertiesConfig props)
|
public MockAC(string key, string name, MockAcPropertiesConfig props)
|
||||||
: base(key, name)
|
: base(key, name)
|
||||||
{
|
{
|
||||||
CodecInfo = new MockAudioCodecInfo();
|
CodecInfo = new MockAudioCodecInfo();
|
||||||
|
|
||||||
CodecInfo.PhoneNumber = props.PhoneNumber;
|
CodecInfo.PhoneNumber = props.PhoneNumber;
|
||||||
|
|
||||||
|
PhonebookEntries = new List<CodecPhonebookEntry>
|
||||||
|
{
|
||||||
|
new() { Name = "Judge Chambers", Number = "5551001" },
|
||||||
|
new() { Name = "Clerk Office", Number = "5551002" },
|
||||||
|
new() { Name = "Court Reporter", Number = "5551003" },
|
||||||
|
new() { Name = "Jury Room", Number = "5551004" },
|
||||||
|
new() { Name = "Witness Room", Number = "5551005" },
|
||||||
|
new() { Name = "Prosecution", Number = "5551006" },
|
||||||
|
new() { Name = "Defense Counsel", Number = "5551007" },
|
||||||
|
new() { Name = "Bailiff Station", Number = "5551008" },
|
||||||
|
new() { Name = "Conference Room A", Number = "5551009" },
|
||||||
|
new() { Name = "Conference Room B", Number = "5551010" },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Dial(string number)
|
public override void Dial(string number)
|
||||||
{
|
{
|
||||||
if (!IsInCall)
|
if (!IsInCall)
|
||||||
|
|
@ -79,6 +99,29 @@ public class MockAC : AudioCodecBase
|
||||||
Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s);
|
Debug.LogMessage(LogEventLevel.Debug, this, "BEEP BOOP SendDTMF: {0}", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetPhonebookEntry(int index, string name, string number)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= PhonebookEntries.Count)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, this, "SetPhonebookEntry: index {0} out of range", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhonebookEntries[index] = new CodecPhonebookEntry { Name = name, Number = number };
|
||||||
|
ListChanged?.Invoke(this, new PhonebookListChangedEventArgs(PhonebookEntries));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DialPhonebookEntry(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= PhonebookEntries.Count)
|
||||||
|
{
|
||||||
|
Debug.LogMessage(LogEventLevel.Debug, this, "DialPhonebookEntry: index {0} out of range", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dial(PhonebookEntries[index].Number);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
: base(key, messagePath, device)
|
: base(key, messagePath, device)
|
||||||
{
|
{
|
||||||
_phonebook = device as IAudioCodecPhonebook ?? throw new ArgumentNullException(nameof(device));
|
_phonebook = device as IAudioCodecPhonebook ?? throw new ArgumentNullException(nameof(device));
|
||||||
|
|
||||||
|
_phonebook.ListChanged += (sender, args) => SendFullStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -43,7 +45,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
var entry = content.ToObject<SetPhonebookEntryContent>();
|
var entry = content.ToObject<SetPhonebookEntryContent>();
|
||||||
_phonebook.SetPhonebookEntry(entry.Index, entry.Name, entry.Number);
|
_phonebook.SetPhonebookEntry(entry.Index, entry.Name, entry.Number);
|
||||||
SendFullStatus();
|
});
|
||||||
|
|
||||||
|
AddAction("/dialEntry", (id, content) =>
|
||||||
|
{
|
||||||
|
var request = content.ToObject<MobileControlSimpleContent<int>>();
|
||||||
|
_phonebook.DialPhonebookEntry(request.Value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,16 @@ namespace PepperDash.Essentials
|
||||||
(d, mp, ck) => new IDialerCallStatusMessenger(
|
(d, mp, ck) => new IDialerCallStatusMessenger(
|
||||||
$"{d.Key}-audioCodec-{ck}", (IDialerCallStatus)d, mp)
|
$"{d.Key}-audioCodec-{ck}", (IDialerCallStatus)d, mp)
|
||||||
),
|
),
|
||||||
|
new MessengerFactoryEntry(
|
||||||
|
typeof(IAudioCodecInfo),
|
||||||
|
(d, mp, ck) => new IAudioCodecInfoMessenger(
|
||||||
|
$"{d.Key}-audioCodecInfo-{ck}", mp, d)
|
||||||
|
),
|
||||||
|
new MessengerFactoryEntry(
|
||||||
|
typeof(IAudioCodecPhonebook),
|
||||||
|
(d, mp, ck) => new IAudioCodecPhonebookMessenger(
|
||||||
|
$"{d.Key}-audioCodecPhonebook-{ck}", mp, d)
|
||||||
|
),
|
||||||
|
|
||||||
// ── Set-top box controls ──────────────────────────────────────────────────
|
// ── Set-top box controls ──────────────────────────────────────────────────
|
||||||
new MessengerFactoryEntry(
|
new MessengerFactoryEntry(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue