mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-27 11:24:55 +00:00
Compare commits
39 Commits
1.6.5-alph
...
1.6.5-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e01455140 | ||
|
|
1ea80c3fab | ||
|
|
1676f5a956 | ||
|
|
cdc9cdbe95 | ||
|
|
28e8a1fb11 | ||
|
|
5f1b92ca62 | ||
|
|
c58a1874ca | ||
|
|
f4fb9cd173 | ||
|
|
ad4a6e9383 | ||
|
|
decdaf9f1f | ||
|
|
27382a6be1 | ||
|
|
34440af1c5 | ||
|
|
c0e3da9214 | ||
|
|
d50ad7345d | ||
|
|
95016c3ec6 | ||
|
|
f8f5c2474c | ||
|
|
b997e9a135 | ||
|
|
c7ccac2fe6 | ||
|
|
05885f568e | ||
|
|
b500b9f6cc | ||
|
|
e784c08f80 | ||
|
|
45ea5cc875 | ||
|
|
a006698bb2 | ||
|
|
e365944dc3 | ||
|
|
c33dcb78d0 | ||
|
|
e48ec3af7c | ||
|
|
4b9d7d1a1f | ||
|
|
d6133905b2 | ||
|
|
741b401d8c | ||
|
|
cb661313c2 | ||
|
|
3c794849bd | ||
|
|
753b4e69ee | ||
|
|
b502007fff | ||
|
|
1e6d65fe53 | ||
|
|
72515a79ca | ||
|
|
d2eadcd2f5 | ||
|
|
13dabc09c7 | ||
|
|
0fc6a73b30 | ||
|
|
8f319a4405 |
@@ -327,7 +327,11 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
|
||||
|
||||
// Add global System Monitor device
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
|
||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||
{
|
||||
DeviceManager.AddDevice(
|
||||
new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
|
||||
}
|
||||
|
||||
foreach (var devConf in ConfigReader.ConfigObject.Devices)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
@@ -82,9 +84,9 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
|
||||
protected Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
|
||||
|
||||
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
|
||||
public BasicTriList Eisc { get; private set; }
|
||||
|
||||
public EiscApiAdvanced(DeviceConfig dc) :
|
||||
public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) :
|
||||
base(dc.Key)
|
||||
{
|
||||
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
|
||||
@@ -92,44 +94,52 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
PropertiesConfig = dc.Properties.ToObject<EiscApiPropertiesConfig>();
|
||||
//PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem);
|
||||
Eisc = eisc;
|
||||
|
||||
Eisc.SigChange += Eisc_SigChange;
|
||||
|
||||
AddPostActivationAction( () =>
|
||||
AddPostActivationAction(LinkDevices);
|
||||
}
|
||||
|
||||
private void LinkDevices()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Devices...");
|
||||
|
||||
foreach (var d in PropertiesConfig.Devices)
|
||||
{
|
||||
Debug.Console(1, this, "Linking Devices...");
|
||||
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||
|
||||
foreach (var d in PropertiesConfig.Devices)
|
||||
if (device == null)
|
||||
{
|
||||
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||
|
||||
if (device == null) continue;
|
||||
|
||||
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||
|
||||
if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
|
||||
device.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
var bridge = device as IBridgeAdvanced;
|
||||
if (bridge != null) bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
|
||||
continue;
|
||||
}
|
||||
|
||||
var registerResult = Eisc.Register();
|
||||
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||
|
||||
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
|
||||
{
|
||||
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Registration result: {0}", registerResult);
|
||||
return;
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
|
||||
device.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||
});
|
||||
var bridge = device as IBridgeAdvanced;
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
|
||||
}
|
||||
}
|
||||
|
||||
var registerResult = Eisc.Register();
|
||||
|
||||
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
{
|
||||
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Registration result: {0}", registerResult);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -152,7 +162,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <summary>
|
||||
/// Prints all the join maps on this bridge
|
||||
/// </summary>
|
||||
public void PrintJoinMaps()
|
||||
public virtual void PrintJoinMaps()
|
||||
{
|
||||
Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X"));
|
||||
|
||||
@@ -247,7 +257,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// </summary>
|
||||
/// <param name="currentDevice"></param>
|
||||
/// <param name="args"></param>
|
||||
void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
||||
protected void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -299,15 +309,34 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public EiscApiAdvancedFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced" };
|
||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "vceiscapiadv", "vceiscapiadvanced" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new EiscApiAdvanced Device");
|
||||
|
||||
return new EiscApiAdvanced(dc);
|
||||
|
||||
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
|
||||
|
||||
switch (dc.Type.ToLower())
|
||||
{
|
||||
case "eiscapiadv":
|
||||
case "eiscapiadvanced":
|
||||
{
|
||||
var eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
|
||||
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
||||
return new EiscApiAdvanced(dc, eisc);
|
||||
}
|
||||
case "vceiscapiadv":
|
||||
case "vceiscapiadvanced":
|
||||
{
|
||||
var eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, InitialParametersClass.RoomId,
|
||||
Global.ControlSystem);
|
||||
return new EiscApiAdvanced(dc, eisc);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,15 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraLayoutStringFb")] public JoinDataComplete CameraLayoutStringFb =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 141, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Layout Fb",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("CameraModeAuto")] public JoinDataComplete CameraModeAuto =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 131, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
@@ -90,6 +99,15 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraPresetNames")] public JoinDataComplete CameraPresetNames =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 121, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Camera Preset Names - XSIG, max of 15",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CameraPresetSelect")] public JoinDataComplete CameraPresetSelect =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 121, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
@@ -99,13 +117,13 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("CameraPresetNames")] public JoinDataComplete CameraPresetNames =
|
||||
[JoinName("CameraPresetSave")] public JoinDataComplete CameraPresetSave =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 121, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Camera Preset Names - XSIG, max of 15",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
Description = "Save Selected Preset",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CameraSelfView")] public JoinDataComplete CameraSelfView =
|
||||
@@ -189,15 +207,53 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DirectoryHasChanged")] public JoinDataComplete DirectoryHasChanged =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 103, JoinSpan = 1},
|
||||
[JoinName("CurrentParticipants")] public JoinDataComplete CurrentParticipants =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 151, JoinSpan = 1},
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Participants XSig",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentSource")] public JoinDataComplete CurrentSource =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 201, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Directory has changed FB",
|
||||
Description = "Current Source",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DialMeeting1")] public JoinDataComplete DialMeeting1 =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 161, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Join first meeting",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DialMeeting2")]
|
||||
public JoinDataComplete DialMeeting2 =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Join second meeting",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DialMeeting3")]
|
||||
public JoinDataComplete DialMeeting3 =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Join third meeting",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryDialSelectedLine")] public JoinDataComplete DirectoryDialSelectedLine =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 106, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
@@ -252,6 +308,15 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryHasChanged")] public JoinDataComplete DirectoryHasChanged =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 103, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Directory has changed FB",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DirectoryIsRoot")] public JoinDataComplete DirectoryIsRoot =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 102, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
@@ -495,37 +560,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SpeedDialStart")] public JoinDataComplete SpeedDialStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 4},
|
||||
|
||||
[JoinName("ManualDial")] public JoinDataComplete ManualDial =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 71, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Speed Dial",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Schedule")] public JoinDataComplete Schedule =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 102, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Schedule Data - XSIG",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("DialMeeting")] public JoinDataComplete DialMeeting = new JoinDataComplete(new JoinData{JoinNumber=161, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Join first joinable meeting",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("UpdateMeetings")] public JoinDataComplete UpdateMeetings =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 162, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Update Meetings",
|
||||
Description = "Dial manual string",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
@@ -539,82 +579,15 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
|
||||
[JoinName("CameraLayoutStringFb")]
|
||||
public JoinDataComplete CameraLayoutStringFb =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Layout Fb",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
[JoinName("ManualDial")] public JoinDataComplete ManualDial =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 71, JoinSpan = 1},
|
||||
[JoinName("MicMuteOff")] public JoinDataComplete MicMuteOff =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 172, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Dial manual string",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceShareStart")] public JoinDataComplete SourceShareStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 201, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Start Sharing & Feedback",
|
||||
Description = "Mic Mute Off",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceShareEnd")]
|
||||
public JoinDataComplete SourceShareEnd =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Stop Sharing & Feedback",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("AutoShareWhileInCall")] public JoinDataComplete SourceShareAutoStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 203, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "When high, will autostart sharing when a call is joined",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CurrentSource")] public JoinDataComplete CurrentSource = new JoinDataComplete(new JoinData{JoinNumber = 201, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Source",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentParticipants")] public JoinDataComplete CurrentParticipants =
|
||||
new JoinDataComplete(new JoinData{JoinNumber = 151, JoinSpan = 1},
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Participants XSig",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ParticipantCount")] public JoinDataComplete ParticipantCount = new JoinDataComplete(new JoinData{JoinNumber = 151, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Participant Count",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("MicMuteOn")] public JoinDataComplete MicMuteOn =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 171, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
@@ -624,15 +597,6 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("MicMuteOff")] public JoinDataComplete MicMuteOff =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 172, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Mic Mute Off",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("MicMuteToggle")] public JoinDataComplete MicMuteToggle =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 173, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
@@ -642,35 +606,150 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeMuteOn")]
|
||||
public JoinDataComplete VolumeMuteOn =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 },
|
||||
[JoinName("MinutesBeforeMeetingStart")] public JoinDataComplete MinutesBeforeMeetingStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Minutes before meeting start that a meeting is joinable",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("ParticipantCount")] public JoinDataComplete ParticipantCount =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 151, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Participant Count",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("Schedule")] public JoinDataComplete Schedule =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 102, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Schedule Data - XSIG",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("AutoShareWhileInCall")] public JoinDataComplete SourceShareAutoStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 203, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "When high, will autostart sharing when a call is joined",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceShareEnd")] public JoinDataComplete SourceShareEnd =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 202, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Stop Sharing & Feedback",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceShareStart")] public JoinDataComplete SourceShareStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 201, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Start Sharing & Feedback",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("RecievingContent")] public JoinDataComplete RecievingContent =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 204, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Recieving content from the far end",
|
||||
JoinType = eJoinType.Digital,
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL
|
||||
});
|
||||
|
||||
[JoinName("SelfviewPosition")] public JoinDataComplete SelfviewPosition =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 211, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "advance selfview position",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SelfviewPositionFb")]
|
||||
public JoinDataComplete SelfviewPositionFb =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute On",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
Description = "advance selfview position",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("VolumeMuteOff")]
|
||||
public JoinDataComplete VolumeMuteOff =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute Off",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("SpeedDialStart")] public JoinDataComplete SpeedDialStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 4},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Speed Dial",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeMuteToggle")]
|
||||
public JoinDataComplete VolumeMuteToggle =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute Toggle",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("UpdateMeetings")] public JoinDataComplete UpdateMeetings =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 160, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Update Meetings",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeDown")] public JoinDataComplete VolumeDown =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 175, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Down",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeLevel")] public JoinDataComplete VolumeLevel =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 174, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Level",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("VolumeMuteOff")] public JoinDataComplete VolumeMuteOff =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 177, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute Off",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeMuteOn")] public JoinDataComplete VolumeMuteOn =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 176, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute On",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeMuteToggle")] public JoinDataComplete VolumeMuteToggle =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 178, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Mute Toggle",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeUp")] public JoinDataComplete VolumeUp =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 174, JoinSpan = 1},
|
||||
@@ -681,34 +760,45 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeDown")]
|
||||
public JoinDataComplete VolumeDown =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 },
|
||||
[JoinName("DialPhoneCall")]
|
||||
public JoinDataComplete DialPhone =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Down",
|
||||
Description = "Dial Phone",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("VolumeLevel")]
|
||||
public JoinDataComplete VolumeLevel =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 },
|
||||
[JoinName("PhoneHookState")]
|
||||
public JoinDataComplete PhoneHookState =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Volume Level",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
Description = "Dial Phone",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("MinutesBeforeMeetingStart")] public JoinDataComplete MinutesBeforeMeetingStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Minutes before meeting start that a meeting is joinable",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
[JoinName("EndPhoneCall")]
|
||||
public JoinDataComplete HangUpPhone =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Hang Up PHone",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PhoneString")]
|
||||
public JoinDataComplete PhoneDialString =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Phone Dial String",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof (VideoCodecControllerJoinMap))
|
||||
{
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
using System;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CommFactory
|
||||
{
|
||||
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||
(deviceConfig.Properties["control"].ToString());
|
||||
//Debug.Console(2, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Debug.Console(0, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||
/// </summary>
|
||||
/// <param name="deviceConfig">The Device config object</param>
|
||||
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||
{
|
||||
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||
if (controlConfig == null)
|
||||
return null;
|
||||
|
||||
IBasicCommunication comm = null;
|
||||
try
|
||||
{
|
||||
var c = controlConfig.TcpSshProperties;
|
||||
switch (controlConfig.Method)
|
||||
{
|
||||
case eControlMethod.Com:
|
||||
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams, controlConfig);
|
||||
break;
|
||||
case eControlMethod.Cec:
|
||||
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
||||
break;
|
||||
case eControlMethod.IR:
|
||||
break;
|
||||
case eControlMethod.Ssh:
|
||||
{
|
||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
||||
ssh.AutoReconnect = c.AutoReconnect;
|
||||
if(ssh.AutoReconnect)
|
||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = ssh;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Tcpip:
|
||||
{
|
||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
||||
tcp.AutoReconnect = c.AutoReconnect;
|
||||
if (tcp.AutoReconnect)
|
||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = tcp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Udp:
|
||||
{
|
||||
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||
comm = udp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Telnet:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
||||
deviceConfig.Properties.ToString(), e);
|
||||
}
|
||||
|
||||
// put it in the device manager if it's the right flavor
|
||||
var comDev = comm as Device;
|
||||
if (comDev != null)
|
||||
DeviceManager.AddDevice(comDev);
|
||||
return comm;
|
||||
}
|
||||
|
||||
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||
{
|
||||
var comPar = config.ComParams;
|
||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||
return dev.ComPorts[config.ControlPortNumber];
|
||||
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||
{
|
||||
using System;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CommFactory
|
||||
{
|
||||
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||
(deviceConfig.Properties["control"].ToString());
|
||||
//Debug.Console(2, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Debug.Console(0, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||
/// </summary>
|
||||
/// <param name="deviceConfig">The Device config object</param>
|
||||
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||
{
|
||||
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||
if (controlConfig == null)
|
||||
return null;
|
||||
|
||||
IBasicCommunication comm = null;
|
||||
try
|
||||
{
|
||||
var c = controlConfig.TcpSshProperties;
|
||||
switch (controlConfig.Method)
|
||||
{
|
||||
case eControlMethod.Com:
|
||||
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams, controlConfig);
|
||||
break;
|
||||
case eControlMethod.Cec:
|
||||
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
||||
break;
|
||||
case eControlMethod.IR:
|
||||
break;
|
||||
case eControlMethod.Ssh:
|
||||
{
|
||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
||||
ssh.AutoReconnect = c.AutoReconnect;
|
||||
if(ssh.AutoReconnect)
|
||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = ssh;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Tcpip:
|
||||
{
|
||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
||||
tcp.AutoReconnect = c.AutoReconnect;
|
||||
if (tcp.AutoReconnect)
|
||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = tcp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Udp:
|
||||
{
|
||||
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||
comm = udp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Telnet:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
||||
deviceConfig.Properties.ToString(), e);
|
||||
}
|
||||
|
||||
// put it in the device manager if it's the right flavor
|
||||
var comDev = comm as Device;
|
||||
if (comDev != null)
|
||||
DeviceManager.AddDevice(comDev);
|
||||
return comm;
|
||||
}
|
||||
|
||||
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||
{
|
||||
var comPar = config.ComParams;
|
||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||
return dev.ComPorts[config.ControlPortNumber];
|
||||
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
||||
|
||||
if (dev != null)
|
||||
@@ -147,64 +147,64 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "GetCecPort: Device '{0}' is not a valid device.", config.ControlPortDevKey);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||
/// return the ControlSystem object from the Global class.
|
||||
/// </summary>
|
||||
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||
{
|
||||
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
|
||||
&& Global.ControlSystem is IComPorts)
|
||||
return Global.ControlSystem;
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
||||
if (dev == null)
|
||||
Debug.Console(0, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsControlPropertiesConfig :
|
||||
PepperDash.Core.ControlPropertiesConfig
|
||||
{
|
||||
|
||||
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||
public ComPort.ComPortSpec ComParams { get; set; }
|
||||
|
||||
public string CresnetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to provide uint conversion of string CresnetId
|
||||
/// </summary>
|
||||
public uint CresnetIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(CresnetId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "GetCecPort: Device '{0}' is not a valid device.", config.ControlPortDevKey);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string InfinetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||
/// return the ControlSystem object from the Global class.
|
||||
/// </summary>
|
||||
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||
{
|
||||
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
|
||||
&& Global.ControlSystem is IComPorts)
|
||||
return Global.ControlSystem;
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
||||
if (dev == null)
|
||||
Debug.Console(0, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsControlPropertiesConfig :
|
||||
PepperDash.Core.ControlPropertiesConfig
|
||||
{
|
||||
|
||||
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||
public ComPort.ComPortSpec ComParams { get; set; }
|
||||
|
||||
public string CresnetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to provide uint conversion of string CresnetId
|
||||
/// </summary>
|
||||
public uint CresnetIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(CresnetId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string InfinetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attepmts to provide uiont conversion of string InifinetId
|
||||
/// </summary>
|
||||
@@ -221,13 +221,13 @@ namespace PepperDash.Essentials.Core
|
||||
throw new FormatException(string.Format("ERROR:Unable to conver Infinet ID: {0} to hex. Error:\n{1}", InfinetId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IrControlSpec
|
||||
{
|
||||
public string PortDeviceKey { get; set; }
|
||||
public uint PortNumber { get; set; }
|
||||
public string File { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IrControlSpec
|
||||
{
|
||||
public string PortDeviceKey { get; set; }
|
||||
public uint PortNumber { get; set; }
|
||||
public string File { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace PepperDash.Essentials.Core.Config
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>,
|
||||
/// The OS Version of the processor (Firmware Version)
|
||||
/// </summary>
|
||||
[JsonProperty("osVersion")]
|
||||
@@ -92,5 +92,18 @@ namespace PepperDash.Essentials.Core.Config
|
||||
// return Crestron.SimplSharp.CrestronEnvironment.OSVersion.Firmware;
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// The information gathered by the processor at runtime about it's NICs and their IP addresses.
|
||||
/// </summary>
|
||||
[JsonProperty("ipInfo")]
|
||||
public Dictionary<short, EthernetAdapterInfo> IpInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return Global.EthernetAdapterInfoCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasFarEndContentStatus
|
||||
{
|
||||
BoolFeedback ReceivingContent { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasPhoneDialing
|
||||
{
|
||||
BoolFeedback PhoneOffHookFeedback { get; }
|
||||
StringFeedback CallerIdNameFeedback { get; }
|
||||
StringFeedback CallerIdNumberFeedback { get; }
|
||||
void DialPhoneCall(string number);
|
||||
void EndPhoneCall();
|
||||
void SendDtmfToPhone(string digit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class EthernetAdapterInfo
|
||||
{
|
||||
public EthernetAdapterType Type { get; set; }
|
||||
public bool DhcpIsOn { get; set; }
|
||||
public string Hostname { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string IpAddress { get; set; }
|
||||
public string Subnet { get; set; }
|
||||
public string Gateway { get; set; }
|
||||
public string Dns1 { get; set; }
|
||||
public string Dns2 { get; set; }
|
||||
public string Dns3 { get; set; }
|
||||
public string Domain { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,175 +1,180 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.CrestronDataStore;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.License;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.CrestronDataStore;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.License;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
public static CrestronControlSystem ControlSystem { get; set; }
|
||||
|
||||
public static LicenseManager LicenseManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the folder containing configuration files
|
||||
/// </summary>
|
||||
public static string FilePathPrefix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the applciation directory
|
||||
/// </summary>
|
||||
public static string ApplicationDirectoryPathPrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return Crestron.SimplSharp.CrestronIO.Directory.GetApplicationDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the directory separator character based on the running OS
|
||||
/// </summary>
|
||||
public static char DirectorySeparator
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.IO.Path.DirectorySeparatorChar;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wildcarded config file name for global reference
|
||||
/// </summary>
|
||||
public const string ConfigFileName = "*configurationFile*.json";
|
||||
|
||||
/// <summary>
|
||||
/// Sets the file path prefix
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
public static void SetFilePathPrefix(string prefix)
|
||||
{
|
||||
FilePathPrefix = prefix;
|
||||
}
|
||||
|
||||
static string _AssemblyVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Assembly Version of Essentials
|
||||
/// </summary>
|
||||
/// <returns>The Assembly Version at Runtime</returns>
|
||||
public static string AssemblyVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return _AssemblyVersion;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_AssemblyVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Assembly version to the version of the Essentials Library
|
||||
/// </summary>
|
||||
/// <param name="assemblyVersion"></param>
|
||||
public static void SetAssemblyVersion(string assemblyVersion)
|
||||
{
|
||||
AssemblyVersion = assemblyVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the running version meets or exceed the minimum specified version. For beta versions (0.xx.yy), will always return true.
|
||||
/// </summary>
|
||||
/// <param name="minimumVersion">Minimum specified version in format of xx.yy.zz</param>
|
||||
/// <returns>Returns true if the running version meets or exceeds the minimum specified version</returns>
|
||||
public static bool IsRunningMinimumVersionOrHigher(string minimumVersion)
|
||||
{
|
||||
Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion);
|
||||
|
||||
if (String.IsNullOrEmpty(minimumVersion))
|
||||
{
|
||||
Debug.Console(0,"Plugin does not specify a minimum version. Loading plugin may not work as expected. Proceeding with loading plugin");
|
||||
return true;
|
||||
}
|
||||
|
||||
var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*");
|
||||
|
||||
var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value);
|
||||
var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value);
|
||||
var runtimeVersionBuild = Int16.Parse(runtimeVersion.Groups[3].Value);
|
||||
|
||||
var runtimeVer = new Version(runtimeVersionMajor, runtimeVersionMinor, runtimeVersionBuild);
|
||||
|
||||
Version minimumVer;
|
||||
try
|
||||
{
|
||||
minimumVer = new Version(minimumVersion);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "unable to parse minimum version {0}. Bypassing plugin load.", minimumVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check for beta build version
|
||||
if (runtimeVer.Major != 0)
|
||||
{
|
||||
return runtimeVer.CompareTo(minimumVer) >= 0;
|
||||
}
|
||||
|
||||
Debug.Console(2, "Running Local Build. Bypassing Dependency Check.");
|
||||
return true;
|
||||
|
||||
/*
|
||||
var minVersion = Regex.Match(minimumVersion, @"^(\d*).(\d*).(\d*)$");
|
||||
|
||||
if(!minVersion.Success)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var minVersionMajor = Int16.Parse(minVersion.Groups[1].Value);
|
||||
var minVersionMinor = Int16.Parse(minVersion.Groups[2].Value);
|
||||
var minVersionBuild = Int16.Parse(minVersion.Groups[3].Value);
|
||||
|
||||
|
||||
|
||||
if (minVersionMajor > runtimeVersionMajor)
|
||||
return false;
|
||||
|
||||
if (minVersionMinor > runtimeVersionMinor)
|
||||
return false;
|
||||
|
||||
if (minVersionBuild > runtimeVersionBuild)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
static Global()
|
||||
{
|
||||
// Fire up CrestronDataStoreStatic
|
||||
var err = CrestronDataStoreStatic.InitCrestronDataStore();
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
{
|
||||
CrestronConsole.PrintLine("Error starting CrestronDataStoreStatic: {0}", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static eDevicePlatform Platform { get { return CrestronEnvironment.DevicePlatform; } }
|
||||
|
||||
public static Dictionary<short, EthernetAdapterInfo> EthernetAdapterInfoCollection { get; private set; }
|
||||
|
||||
public static LicenseManager LicenseManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the folder containing configuration files
|
||||
/// </summary>
|
||||
public static string FilePathPrefix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the applciation directory
|
||||
/// </summary>
|
||||
public static string ApplicationDirectoryPathPrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return Crestron.SimplSharp.CrestronIO.Directory.GetApplicationDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the directory separator character based on the running OS
|
||||
/// </summary>
|
||||
public static char DirectorySeparator
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.IO.Path.DirectorySeparatorChar;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wildcarded config file name for global reference
|
||||
/// </summary>
|
||||
public const string ConfigFileName = "*configurationFile*.json";
|
||||
|
||||
/// <summary>
|
||||
/// Sets the file path prefix
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
public static void SetFilePathPrefix(string prefix)
|
||||
{
|
||||
FilePathPrefix = prefix;
|
||||
}
|
||||
|
||||
static string _AssemblyVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Assembly Version of Essentials
|
||||
/// </summary>
|
||||
/// <returns>The Assembly Version at Runtime</returns>
|
||||
public static string AssemblyVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return _AssemblyVersion;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_AssemblyVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Assembly version to the version of the Essentials Library
|
||||
/// </summary>
|
||||
/// <param name="assemblyVersion"></param>
|
||||
public static void SetAssemblyVersion(string assemblyVersion)
|
||||
{
|
||||
AssemblyVersion = assemblyVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the running version meets or exceed the minimum specified version. For beta versions (0.xx.yy), will always return true.
|
||||
/// </summary>
|
||||
/// <param name="minimumVersion">Minimum specified version in format of xx.yy.zz</param>
|
||||
/// <returns>Returns true if the running version meets or exceeds the minimum specified version</returns>
|
||||
public static bool IsRunningMinimumVersionOrHigher(string minimumVersion)
|
||||
{
|
||||
Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion);
|
||||
|
||||
if (String.IsNullOrEmpty(minimumVersion))
|
||||
{
|
||||
Debug.Console(0,"Plugin does not specify a minimum version. Loading plugin may not work as expected. Proceeding with loading plugin");
|
||||
return true;
|
||||
}
|
||||
|
||||
var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*");
|
||||
|
||||
var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value);
|
||||
var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value);
|
||||
var runtimeVersionBuild = Int16.Parse(runtimeVersion.Groups[3].Value);
|
||||
|
||||
var runtimeVer = new Version(runtimeVersionMajor, runtimeVersionMinor, runtimeVersionBuild);
|
||||
|
||||
Version minimumVer;
|
||||
try
|
||||
{
|
||||
minimumVer = new Version(minimumVersion);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "unable to parse minimum version {0}. Bypassing plugin load.", minimumVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check for beta build version
|
||||
if (runtimeVer.Major != 0)
|
||||
{
|
||||
return runtimeVer.CompareTo(minimumVer) >= 0;
|
||||
}
|
||||
|
||||
Debug.Console(2, "Running Local Build. Bypassing Dependency Check.");
|
||||
return true;
|
||||
|
||||
/*
|
||||
var minVersion = Regex.Match(minimumVersion, @"^(\d*).(\d*).(\d*)$");
|
||||
|
||||
if(!minVersion.Success)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var minVersionMajor = Int16.Parse(minVersion.Groups[1].Value);
|
||||
var minVersionMinor = Int16.Parse(minVersion.Groups[2].Value);
|
||||
var minVersionBuild = Int16.Parse(minVersion.Groups[3].Value);
|
||||
|
||||
|
||||
|
||||
if (minVersionMajor > runtimeVersionMajor)
|
||||
return false;
|
||||
|
||||
if (minVersionMinor > runtimeVersionMinor)
|
||||
return false;
|
||||
|
||||
if (minVersionBuild > runtimeVersionBuild)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
static Global()
|
||||
{
|
||||
// Fire up CrestronDataStoreStatic
|
||||
var err = CrestronDataStoreStatic.InitCrestronDataStore();
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
{
|
||||
CrestronConsole.PrintLine("Error starting CrestronDataStoreStatic: {0}", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -196,6 +196,8 @@
|
||||
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasBranding.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
|
||||
<Compile Include="Factory\DeviceFactory.cs" />
|
||||
<Compile Include="Factory\IDeviceFactory.cs" />
|
||||
@@ -213,6 +215,7 @@
|
||||
<Compile Include="Fusion\FusionRviDataClasses.cs" />
|
||||
<Compile Include="Gateways\CenRfgwController.cs" />
|
||||
<Compile Include="Gateways\EssentialsRfGatewayConfig.cs" />
|
||||
<Compile Include="Global\EthernetAdapterInfo.cs" />
|
||||
<Compile Include="Queues\ComsMessage.cs" />
|
||||
<Compile Include="Queues\ProcessStringMessage.cs" />
|
||||
<Compile Include="Queues\GenericQueue.cs" />
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
|
||||
public class CodecScheduleAwareness
|
||||
{
|
||||
List<Meeting> _Meetings;
|
||||
List<Meeting> _meetings;
|
||||
|
||||
public event EventHandler<MeetingEventArgs> MeetingEventChange;
|
||||
|
||||
@@ -45,11 +45,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Meetings;
|
||||
return _meetings;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Meetings = value;
|
||||
_meetings = value;
|
||||
|
||||
var handler = MeetingsListHasChanged;
|
||||
if (handler != null)
|
||||
@@ -59,13 +59,20 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
}
|
||||
}
|
||||
|
||||
private CTimer ScheduleChecker;
|
||||
private CTimer _scheduleChecker;
|
||||
|
||||
public CodecScheduleAwareness()
|
||||
{
|
||||
Meetings = new List<Meeting>();
|
||||
|
||||
ScheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000);
|
||||
_scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000);
|
||||
}
|
||||
|
||||
public CodecScheduleAwareness(long pollTime)
|
||||
{
|
||||
Meetings = new List<Meeting>();
|
||||
|
||||
_scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime);
|
||||
}
|
||||
|
||||
private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting)
|
||||
@@ -82,9 +89,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
// Iterate the meeting list and check if any meeting need to do anythingk
|
||||
|
||||
const double meetingTimeEpsilon = 0.0001;
|
||||
foreach (Meeting m in Meetings)
|
||||
foreach (var m in Meetings)
|
||||
{
|
||||
eMeetingEventChangeType changeType = eMeetingEventChangeType.Unkown;
|
||||
var changeType = eMeetingEventChangeType.Unkown;
|
||||
|
||||
if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start
|
||||
changeType = eMeetingEventChangeType.MeetingStartWarning;
|
||||
@@ -108,14 +115,17 @@ namespace PepperDash.Essentials.Devices.Common.Codec
|
||||
/// </summary>
|
||||
public class Meeting
|
||||
{
|
||||
public TimeSpan MeetingWarningMinutes = TimeSpan.FromMinutes(5);
|
||||
|
||||
public int MinutesBeforeMeeting;
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Organizer { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Agenda { get; set; }
|
||||
|
||||
public TimeSpan MeetingWarningMinutes
|
||||
{
|
||||
get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); }
|
||||
}
|
||||
public TimeSpan TimeToMeetingStart
|
||||
{
|
||||
get
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
<Compile Include="Cameras\CameraControl.cs" />
|
||||
<Compile Include="Display\PanasonicThDisplay.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
|
||||
<Compile Include="Codec\iHasCallFavorites.cs" />
|
||||
<Compile Include="Codec\iHasCallHistory.cs" />
|
||||
|
||||
@@ -2103,6 +2103,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Cisco Codec Device");
|
||||
|
||||
var comm = CommFactory.CreateCommForDevice(dc);
|
||||
return new VideoCodec.Cisco.CiscoSparkCodec(dc, comm);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasSelfviewPosition
|
||||
{
|
||||
StringFeedback SelfviewPipPositionFeedback { get; }
|
||||
|
||||
void SelfviewPipPositionSet(CodecCommandWithLabel position);
|
||||
|
||||
void SelfviewPipPositionToggle();
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,13 @@ using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using PepperDash_Essentials_Core.Bridges.JoinMaps;
|
||||
using PepperDash_Essentials_Core.DeviceTypeInterfaces;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
@@ -62,6 +64,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
public bool ShowSelfViewByDefault { get; protected set; }
|
||||
|
||||
protected bool SupportsCameraOff;
|
||||
protected bool SupportsCameraAutoMode;
|
||||
|
||||
public bool IsReady { get; protected set; }
|
||||
|
||||
@@ -133,16 +137,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
get
|
||||
{
|
||||
bool value;
|
||||
|
||||
if (ActiveCalls != null)
|
||||
{
|
||||
value = ActiveCalls.Any(c => c.IsActiveCall);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = false;
|
||||
}
|
||||
var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +200,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
/// <param name="previousStatus"></param>
|
||||
/// <param name="newStatus"></param>
|
||||
/// <param name="item"></param>
|
||||
protected void OnCallStatusChange(CodecActiveCallItem item)
|
||||
protected virtual void OnCallStatusChange(CodecActiveCallItem item)
|
||||
{
|
||||
var handler = CallStatusChange;
|
||||
if (handler != null)
|
||||
@@ -314,15 +309,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode);
|
||||
LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraOff)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff);
|
||||
LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecLayouts)
|
||||
{
|
||||
LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasSelfviewPosition)
|
||||
{
|
||||
LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasDirectory)
|
||||
{
|
||||
LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap);
|
||||
@@ -338,6 +344,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasFarEndContentStatus)
|
||||
{
|
||||
(codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
|
||||
}
|
||||
|
||||
if (codec is IHasPhoneDialing)
|
||||
{
|
||||
LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
@@ -361,20 +377,96 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
|
||||
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.InvokeFireUpdate();
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCodecSelfView)
|
||||
{
|
||||
(codec as IHasCodecSelfView).SelfviewIsOnFeedback.InvokeFireUpdate();
|
||||
(codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
SharingContentIsOnFeedback.InvokeFireUpdate();
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
UpdateCallStatusXSig();
|
||||
if (codec is IHasCameraOff)
|
||||
{
|
||||
(codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasPhoneDialing)
|
||||
{
|
||||
(codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
SharingContentIsOnFeedback.FireUpdate();
|
||||
|
||||
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
|
||||
|
||||
trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
|
||||
};
|
||||
}
|
||||
|
||||
private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]);
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber,
|
||||
() => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue));
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall);
|
||||
}
|
||||
|
||||
private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle);
|
||||
|
||||
codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]);
|
||||
}
|
||||
|
||||
private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff);
|
||||
|
||||
codec.CameraIsOffFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (a.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
|
||||
var autoCodec = codec as IHasCameraAutoMode;
|
||||
|
||||
if (autoCodec == null) return;
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
};
|
||||
|
||||
if (codec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
|
||||
var autoModeCodec = codec as IHasCameraAutoMode;
|
||||
|
||||
if (autoModeCodec == null) return;
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
}
|
||||
|
||||
private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
|
||||
@@ -413,6 +505,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
codec.Participants.ParticipantsListHasChanged += (sender, args) =>
|
||||
{
|
||||
string participantsXSig;
|
||||
|
||||
if (codec.Participants.CurrentParticipants.Count == 0)
|
||||
{
|
||||
participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
|
||||
@@ -421,10 +514,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
return;
|
||||
}
|
||||
|
||||
participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
|
||||
|
||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||
|
||||
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
|
||||
|
||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||
@@ -435,7 +524,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
||||
{
|
||||
const int maxParticipants = 255;
|
||||
const int maxParticipants = 50;
|
||||
const int maxDigitals = 5;
|
||||
const int maxStrings = 1;
|
||||
const int offset = maxDigitals + maxStrings;
|
||||
@@ -447,7 +536,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
foreach (var participant in currentParticipants)
|
||||
{
|
||||
if (meetingIndex > maxParticipants * offset) break;
|
||||
if (meetingIndex >= maxParticipants * offset) break;
|
||||
|
||||
//digitals
|
||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
|
||||
@@ -463,6 +552,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
}
|
||||
|
||||
while (meetingIndex < maxParticipants*offset)
|
||||
{
|
||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
|
||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
|
||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
|
||||
|
||||
//serials
|
||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
||||
|
||||
digitalIndex += maxDigitals;
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
}
|
||||
|
||||
return GetXSigString(tokenArray);
|
||||
}
|
||||
@@ -489,41 +594,52 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
codec.CodecSchedule.MeetingWarningMinutes = i;
|
||||
});
|
||||
|
||||
codec.CodecSchedule.MeetingsListHasChanged += (sender, args) =>
|
||||
{
|
||||
var clearBytes = XSigHelpers.ClearOutputs();
|
||||
codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap);
|
||||
|
||||
trilist.SetString(joinMap.Schedule.JoinNumber,
|
||||
Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
|
||||
|
||||
var meetingsData = UpdateMeetingsListXSig(codec.CodecSchedule.Meetings);
|
||||
|
||||
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.DialMeeting.JoinNumber, () =>
|
||||
codec.CodecSchedule.MeetingEventChange +=
|
||||
(sender, args) =>
|
||||
{
|
||||
if (codec.CodecSchedule.Meetings[0].Joinable)
|
||||
if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning)
|
||||
{
|
||||
Dial(codec.CodecSchedule.Meetings[0]);
|
||||
UpdateMeetingsList(codec, trilist, joinMap);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort) codec.CodecSchedule.Meetings.Count);
|
||||
};
|
||||
private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
var currentTime = DateTime.Now;
|
||||
var currentMeetings =
|
||||
codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
|
||||
|
||||
var meetingsData = UpdateMeetingsListXSig(currentMeetings);
|
||||
|
||||
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
|
||||
{
|
||||
if(codec.CodecSchedule.Meetings[0] != null)
|
||||
Dial(codec.CodecSchedule.Meetings[0]);
|
||||
});
|
||||
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
|
||||
{
|
||||
if (codec.CodecSchedule.Meetings[1] != null)
|
||||
Dial(codec.CodecSchedule.Meetings[1]);
|
||||
});
|
||||
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
|
||||
{
|
||||
if (codec.CodecSchedule.Meetings[2] != null)
|
||||
Dial(codec.CodecSchedule.Meetings[2]);
|
||||
});
|
||||
|
||||
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)currentMeetings.Count);
|
||||
}
|
||||
|
||||
private string UpdateMeetingsListXSig(List<Meeting> meetings)
|
||||
{
|
||||
/*const int maxCalls = 8;
|
||||
const int maxStrings = 5;
|
||||
const int offset = 6;
|
||||
var callIndex = 0;
|
||||
var digitalIndex = maxStrings*maxCalls;
|
||||
*/
|
||||
|
||||
const int maxMeetings = 3;
|
||||
const int maxDigitals = 1;
|
||||
const int maxStrings = 4;
|
||||
const int maxDigitals = 2;
|
||||
const int maxStrings = 7;
|
||||
const int offset = maxDigitals + maxStrings;
|
||||
var digitalIndex = maxStrings*maxMeetings; //15
|
||||
var stringIndex = 0;
|
||||
@@ -533,36 +649,71 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
/*
|
||||
* Digitals
|
||||
* IsJoinable - 1
|
||||
* IsDialable - 2
|
||||
*
|
||||
* Serials
|
||||
* Organizer - 1
|
||||
* Title - 2
|
||||
* Start Time - 3
|
||||
* End Time - 4
|
||||
* Start Date - 3
|
||||
* Start Time - 4
|
||||
* End Date - 5
|
||||
* End Time - 6
|
||||
*/
|
||||
|
||||
|
||||
foreach(var meeting in meetings)
|
||||
{
|
||||
var currentTime = DateTime.Now;
|
||||
|
||||
if(meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue;
|
||||
|
||||
if (meetingIndex > maxMeetings*offset) break;
|
||||
if (meetingIndex >= maxMeetings*offset)
|
||||
{
|
||||
Debug.Console(2, this, "Max Meetings reached");
|
||||
break;}
|
||||
|
||||
//digitals
|
||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable);
|
||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0");
|
||||
|
||||
//serials
|
||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer);
|
||||
tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title);
|
||||
tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToString("MM/dd/yyyy h:mm"));
|
||||
tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.EndTime.ToString("MM/dd/yyyy h:mm"));
|
||||
tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString());
|
||||
tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString());
|
||||
tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString());
|
||||
tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString());
|
||||
tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id);
|
||||
|
||||
|
||||
digitalIndex += maxDigitals;
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
}
|
||||
|
||||
while (meetingIndex < maxMeetings*offset)
|
||||
{
|
||||
Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}",
|
||||
meetingIndex, maxMeetings*offset);
|
||||
|
||||
//digitals
|
||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
||||
|
||||
//serials
|
||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
||||
tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty);
|
||||
tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty);
|
||||
tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty);
|
||||
tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty);
|
||||
tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty);
|
||||
tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty);
|
||||
|
||||
digitalIndex += maxDigitals;
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
}
|
||||
|
||||
return GetXSigString(tokenArray);
|
||||
}
|
||||
|
||||
@@ -656,6 +807,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
//End All calls for now
|
||||
trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls);
|
||||
|
||||
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
|
||||
|
||||
CallStatusChange += (sender, args) =>
|
||||
{
|
||||
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
|
||||
@@ -668,9 +821,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem));
|
||||
}
|
||||
|
||||
var callStatusXsig = UpdateCallStatusXSig();
|
||||
|
||||
trilist.SetString(joinMap.CurrentCallData.JoinNumber, callStatusXsig);
|
||||
trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
|
||||
};
|
||||
}
|
||||
|
||||
@@ -679,26 +830,44 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
const int maxCalls = 8;
|
||||
const int maxStrings = 5;
|
||||
const int offset = 6;
|
||||
var callIndex = 0;
|
||||
var digitalIndex = maxStrings*maxCalls;
|
||||
|
||||
|
||||
var tokenArray = new XSigToken[ActiveCalls.Count*offset]; //set array size for number of calls * pieces of info
|
||||
var stringIndex = 0;
|
||||
var digitalIndex = maxStrings * maxCalls;
|
||||
var arrayIndex = 0;
|
||||
|
||||
var tokenArray = new XSigToken[maxCalls*offset]; //set array size for number of calls * pieces of info
|
||||
|
||||
foreach (var call in ActiveCalls)
|
||||
{
|
||||
var arrayIndex = callIndex;
|
||||
if (arrayIndex >= maxCalls * offset)
|
||||
break;
|
||||
//digitals
|
||||
tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall);
|
||||
|
||||
//serials
|
||||
tokenArray[arrayIndex + 1] = new XSigSerialToken(callIndex + 1, call.Name ?? String.Empty);
|
||||
tokenArray[arrayIndex + 2] = new XSigSerialToken(callIndex + 2, call.Number ?? String.Empty);
|
||||
tokenArray[arrayIndex + 3] = new XSigSerialToken(callIndex + 3, call.Direction.ToString());
|
||||
tokenArray[arrayIndex + 4] = new XSigSerialToken(callIndex + 4, call.Type.ToString());
|
||||
tokenArray[arrayIndex + 5] = new XSigSerialToken(callIndex + 5, call.Status.ToString());
|
||||
tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty);
|
||||
tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty);
|
||||
tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString());
|
||||
tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString());
|
||||
tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString());
|
||||
|
||||
callIndex += offset;
|
||||
arrayIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
digitalIndex++;
|
||||
}
|
||||
while (digitalIndex < maxCalls)
|
||||
{
|
||||
//digitals
|
||||
tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
||||
|
||||
//serials
|
||||
tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
||||
tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty);
|
||||
tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty);
|
||||
tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty);
|
||||
tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty);
|
||||
|
||||
arrayIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
digitalIndex++;
|
||||
}
|
||||
|
||||
@@ -732,10 +901,53 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn);
|
||||
trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff);
|
||||
|
||||
codec.CameraAutoModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraModeAuto.JoinNumber]);
|
||||
codec.CameraAutoModeIsOnFeedback.LinkComplementInputSig(
|
||||
trilist.BooleanInput[joinMap.CameraModeManual.JoinNumber]);
|
||||
|
||||
codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
var offCodec = codec as IHasCameraOff;
|
||||
|
||||
if (offCodec != null)
|
||||
{
|
||||
if (offCodec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
};
|
||||
|
||||
var offModeCodec = codec as IHasCameraOff;
|
||||
|
||||
if (offModeCodec != null)
|
||||
{
|
||||
if (offModeCodec.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
return;
|
||||
}
|
||||
|
||||
trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue);
|
||||
trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false);
|
||||
}
|
||||
|
||||
private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist,
|
||||
@@ -825,8 +1037,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
var i = (ushort) codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key);
|
||||
|
||||
trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i);
|
||||
|
||||
if (codec is IHasCodecRoomPresets)
|
||||
{
|
||||
return;
|
||||
@@ -841,24 +1051,58 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
SetCameraPresetNames(cam.Presets);
|
||||
|
||||
(args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets);
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber,
|
||||
(a) =>
|
||||
{
|
||||
cam.PresetSelect(a);
|
||||
trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a);
|
||||
});
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
|
||||
() =>
|
||||
{
|
||||
cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue,
|
||||
String.Empty);
|
||||
trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
|
||||
});
|
||||
};
|
||||
|
||||
if (!(codec is IHasCodecRoomPresets)) return;
|
||||
|
||||
var presetCodec = codec as IHasCodecRoomPresets;
|
||||
|
||||
presetCodec.CodecRoomPresetsListHasChanged +=
|
||||
(sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets);
|
||||
|
||||
//Camera Presets
|
||||
trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) =>
|
||||
{
|
||||
if (codec.SelectedCamera == null) return;
|
||||
|
||||
var cam = codec.SelectedCamera as IHasCameraPresets;
|
||||
|
||||
if (cam == null) return;
|
||||
|
||||
cam.PresetSelect(i);
|
||||
presetCodec.CodecRoomPresetSelect(i);
|
||||
|
||||
trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i);
|
||||
});
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber,
|
||||
() =>
|
||||
{
|
||||
presetCodec.CodecRoomPresetStore(
|
||||
trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty);
|
||||
trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
private string SetCameraPresetNames(List<CameraPreset> presets)
|
||||
private string SetCameraPresetNames(IEnumerable<CodecRoomPreset> presets)
|
||||
{
|
||||
return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
|
||||
}
|
||||
|
||||
private string SetCameraPresetNames(IEnumerable<CameraPreset> presets)
|
||||
{
|
||||
return SetCameraPresetNames(presets.Select(p => p.Description).ToList());
|
||||
}
|
||||
|
||||
private string SetCameraPresetNames(ICollection<string> presets)
|
||||
{
|
||||
var i = 1; //start index for xsig;
|
||||
|
||||
@@ -866,7 +1110,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
foreach (var preset in presets)
|
||||
{
|
||||
var cameraPreset = new XSigSerialToken(i, preset.Description);
|
||||
var cameraPreset = new XSigSerialToken(i, preset);
|
||||
tokenArray[i - 1] = cameraPreset;
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public List<zStatus.AudioVideoInputOutputLineItem> AudioInputs { get; set; }
|
||||
public List<zStatus.AudioVideoInputOutputLineItem> AudioOuputs { get; set; }
|
||||
public List<zStatus.AudioVideoInputOutputLineItem> Cameras { get; set; }
|
||||
public zEvent.PhoneCallStatus PhoneCall { get; set; }
|
||||
|
||||
public ZoomRoomStatus()
|
||||
{
|
||||
@@ -74,6 +75,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
AudioInputs = new List<zStatus.AudioVideoInputOutputLineItem>();
|
||||
AudioOuputs = new List<zStatus.AudioVideoInputOutputLineItem>();
|
||||
Cameras = new List<zStatus.AudioVideoInputOutputLineItem>();
|
||||
PhoneCall = new zEvent.PhoneCallStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +88,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public zConfiguration.Audio Audio { get; set; }
|
||||
public zConfiguration.Video Video { get; set; }
|
||||
public zConfiguration.Client Client { get; set; }
|
||||
public zConfiguration.Camera Camera { get; set; }
|
||||
|
||||
public ZoomRoomConfiguration()
|
||||
{
|
||||
@@ -93,6 +96,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Audio = new zConfiguration.Audio();
|
||||
Video = new zConfiguration.Video();
|
||||
Client = new zConfiguration.Client();
|
||||
Camera = new zConfiguration.Camera();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +372,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public CallRecordInfo CallRecordInfo { get; set; }
|
||||
|
||||
public zCommand.InfoResult Info { get; set; }
|
||||
private zCommand.InfoResult _info;
|
||||
|
||||
public zCommand.InfoResult Info
|
||||
{
|
||||
get
|
||||
{
|
||||
return _info;
|
||||
}
|
||||
set
|
||||
{
|
||||
_info = value;
|
||||
NotifyPropertyChanged("Info");
|
||||
}
|
||||
}
|
||||
|
||||
public Call()
|
||||
{
|
||||
@@ -685,6 +702,86 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
[JsonProperty("why_cannot_pin_share")]
|
||||
public string WhyCannotPinShare { get; set; }
|
||||
}
|
||||
|
||||
public class PhoneCallStatus:NotifiableObject
|
||||
{
|
||||
private bool _isIncomingCall;
|
||||
private string _peerDisplayName;
|
||||
private string _peerNumber;
|
||||
|
||||
private bool _offHook;
|
||||
|
||||
public string CallId { get; set; }
|
||||
public bool IsIncomingCall {
|
||||
get { return _isIncomingCall; }
|
||||
set
|
||||
{
|
||||
if(value == _isIncomingCall) return;
|
||||
|
||||
_isIncomingCall = value;
|
||||
NotifyPropertyChanged("IsIncomingCall");
|
||||
} }
|
||||
|
||||
public string PeerDisplayName
|
||||
{
|
||||
get { return _peerDisplayName; }
|
||||
set
|
||||
{
|
||||
if (value == _peerDisplayName) return;
|
||||
_peerDisplayName = value;
|
||||
NotifyPropertyChanged("PeerDisplayName");
|
||||
}
|
||||
}
|
||||
|
||||
public string PeerNumber
|
||||
{
|
||||
get { return _peerNumber; }
|
||||
set
|
||||
{
|
||||
if (value == _peerNumber) return;
|
||||
|
||||
_peerNumber = value;
|
||||
NotifyPropertyChanged("PeerNumber");
|
||||
}
|
||||
}
|
||||
|
||||
public string PeerUri { get; set; }
|
||||
|
||||
private ePhoneCallStatus _status;
|
||||
public ePhoneCallStatus Status
|
||||
{
|
||||
get { return _status; }
|
||||
set
|
||||
{
|
||||
_status = value;
|
||||
OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted ||
|
||||
_status == ePhoneCallStatus.PhoneCallStatus_InCall ||
|
||||
_status == ePhoneCallStatus.PhoneCallStatus_Init ||
|
||||
_status == ePhoneCallStatus.PhoneCallStatus_Ringing;
|
||||
}
|
||||
}
|
||||
|
||||
public bool OffHook
|
||||
{
|
||||
get { return _offHook; }
|
||||
set
|
||||
{
|
||||
if (value == _offHook) return;
|
||||
|
||||
_offHook = value;
|
||||
NotifyPropertyChanged("OffHook");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ePhoneCallStatus
|
||||
{
|
||||
PhoneCallStatus_Ringing,
|
||||
PhoneCallStatus_Terminated,
|
||||
PhoneCallStatus_Accepted,
|
||||
PhoneCallStatus_InCall,
|
||||
PhoneCallStatus_Init,
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -698,9 +795,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public bool OptimizeVideoSharing { get; set; }
|
||||
}
|
||||
|
||||
public class Camera
|
||||
public class Camera : NotifiableObject
|
||||
{
|
||||
public bool Mute { get; set; }
|
||||
private bool _mute;
|
||||
|
||||
public bool Mute
|
||||
{
|
||||
get { return _mute; }
|
||||
set
|
||||
{
|
||||
Debug.Console(1, "Camera Mute response received: {0}", value);
|
||||
|
||||
if (value == _mute) return;
|
||||
|
||||
_mute = value;
|
||||
NotifyPropertyChanged("Mute");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Microphone : NotifiableObject
|
||||
@@ -754,12 +865,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
DownLeft
|
||||
}
|
||||
|
||||
public class Layout
|
||||
public class Layout:NotifiableObject
|
||||
{
|
||||
public bool ShareThumb { get; set; }
|
||||
public eLayoutStyle Style { get; set; }
|
||||
public eLayoutSize Size { get; set; }
|
||||
public eLayoutPosition Position { get; set; }
|
||||
|
||||
private eLayoutPosition _position;
|
||||
public eLayoutPosition Position {
|
||||
get { return _position; }
|
||||
set
|
||||
{
|
||||
_position = value;
|
||||
NotifyPropertyChanged("Position");
|
||||
} }
|
||||
}
|
||||
|
||||
public class Lock
|
||||
|
||||
@@ -11,17 +11,22 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using PepperDash_Essentials_Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
||||
IRouting,
|
||||
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants
|
||||
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraAutoMode,
|
||||
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing
|
||||
{
|
||||
private const long MeetingRefreshTimer = 60000;
|
||||
private const uint DefaultMeetingDurationMin = 30;
|
||||
private const string Delimiter = "\x0D\x0A";
|
||||
private readonly CrestronQueue<string> _receiveQueue;
|
||||
@@ -38,23 +43,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
private int _previousVolumeLevel;
|
||||
private CameraBase _selectedCamera;
|
||||
|
||||
private readonly ZoomRoomPropertiesConfig _props;
|
||||
|
||||
public ZoomRoom(DeviceConfig config, IBasicCommunication comm)
|
||||
: base(config)
|
||||
{
|
||||
var props = JsonConvert.DeserializeObject<ZoomRoomPropertiesConfig>(config.Properties.ToString());
|
||||
_props = JsonConvert.DeserializeObject<ZoomRoomPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
// The queue that will collect the repsonses in the order they are received
|
||||
_receiveQueue = new CrestronQueue<string>(25);
|
||||
_receiveQueue = new CrestronQueue<string>(1024);
|
||||
|
||||
// The thread responsible for dequeuing and processing the messages
|
||||
_receiveThread = new Thread(o => ProcessQueue(), null) {Priority = Thread.eThreadPriority.MediumPriority};
|
||||
|
||||
Communication = comm;
|
||||
|
||||
if (props.CommunicationMonitorProperties != null)
|
||||
if (_props.CommunicationMonitorProperties != null)
|
||||
{
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication,
|
||||
props.CommunicationMonitorProperties);
|
||||
_props.CommunicationMonitorProperties);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -89,7 +96,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc);
|
||||
|
||||
CodecSchedule = new CodecScheduleAwareness();
|
||||
CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc);
|
||||
|
||||
CameraAutoModeIsOnFeedback = new BoolFeedback(CameraAutoModeIsOnFeedbackFunc);
|
||||
|
||||
CodecSchedule = new CodecScheduleAwareness(MeetingRefreshTimer);
|
||||
|
||||
ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc);
|
||||
|
||||
SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc);
|
||||
|
||||
SetUpFeedbackActions();
|
||||
|
||||
@@ -98,6 +113,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
SetUpDirectory();
|
||||
|
||||
Participants = new CodecParticipants();
|
||||
|
||||
SupportsCameraOff = _props.SupportsCameraOff;
|
||||
SupportsCameraAutoMode = _props.SupportsCameraAutoMode;
|
||||
|
||||
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
||||
CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
|
||||
CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
|
||||
}
|
||||
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
@@ -142,7 +164,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
protected Func<bool> FarEndIsSharingContentFeedbackFunc
|
||||
{
|
||||
get { return () => false; }
|
||||
get { return () => Status.Call.Sharing.State == zEvent.eSharingState.Receiving; }
|
||||
}
|
||||
|
||||
protected override Func<bool> MuteFeedbackFunc
|
||||
@@ -171,9 +193,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
get { return () => !Configuration.Video.HideConfSelfVideo; }
|
||||
}
|
||||
|
||||
protected Func<bool> CameraIsOffFeedbackFunc
|
||||
{
|
||||
get { return () => Configuration.Call.Camera.Mute; }
|
||||
}
|
||||
|
||||
protected Func<bool> CameraAutoModeIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => false; }
|
||||
}
|
||||
|
||||
protected Func<string> SelfviewPipPositionFeedbackFunc
|
||||
{
|
||||
get { return () => ""; }
|
||||
get { return () => _currentSelfviewPipPosition.Command; }
|
||||
}
|
||||
|
||||
protected Func<string> LocalLayoutFeedbackFunc
|
||||
@@ -373,6 +405,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
SetIsReady();
|
||||
}
|
||||
|
||||
private void SetUpCallFeedbackActions()
|
||||
{
|
||||
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
||||
{
|
||||
if (a.PropertyName == "State")
|
||||
{
|
||||
SharingContentIsOnFeedback.FireUpdate();
|
||||
ReceivingContent.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
Status.Call.PropertyChanged += (o, a) =>
|
||||
{
|
||||
if (a.PropertyName == "Info")
|
||||
{
|
||||
Debug.Console(1, this, "Updating Call Status");
|
||||
UpdateCallStatus();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to the PropertyChanged events on the state objects and fires the corresponding feedbacks.
|
||||
@@ -412,11 +464,40 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
};
|
||||
|
||||
Configuration.Call.Camera.PropertyChanged += (o, a) =>
|
||||
{
|
||||
Debug.Console(1, this, "Configuration.Call.Camera.PropertyChanged: {0}", a.PropertyName);
|
||||
|
||||
if (a.PropertyName != "Mute") return;
|
||||
|
||||
CameraIsOffFeedback.FireUpdate();
|
||||
CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
};
|
||||
|
||||
Configuration.Call.Layout.PropertyChanged += (o, a) =>
|
||||
{
|
||||
if (a.PropertyName != "Position") return;
|
||||
|
||||
ComputeSelfviewPipStatus();
|
||||
|
||||
SelfviewPipPositionFeedback.FireUpdate();
|
||||
};
|
||||
|
||||
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
||||
{
|
||||
if (a.PropertyName == "State")
|
||||
{
|
||||
SharingContentIsOnFeedback.FireUpdate();
|
||||
ReceivingContent.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
Status.Call.PropertyChanged += (o, a) =>
|
||||
{
|
||||
if (a.PropertyName == "Info")
|
||||
{
|
||||
Debug.Console(1, this, "Updating Call Status");
|
||||
UpdateCallStatus();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -431,6 +512,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Status.PhoneCall.PropertyChanged += (o, a) =>
|
||||
{
|
||||
switch (a.PropertyName)
|
||||
{
|
||||
case "IsIncomingCall":
|
||||
Debug.Console(1, this, "Incoming Phone Call: {0}", Status.PhoneCall.IsIncomingCall);
|
||||
break;
|
||||
case "PeerDisplayName":
|
||||
Debug.Console(1, this, "Peer Display Name: {0}", Status.PhoneCall.PeerDisplayName);
|
||||
CallerIdNameFeedback.FireUpdate();
|
||||
break;
|
||||
case "PeerNumber":
|
||||
Debug.Console(1, this, "Peer Number: {0}", Status.PhoneCall.PeerNumber);
|
||||
CallerIdNumberFeedback.FireUpdate();
|
||||
break;
|
||||
case "OffHook":
|
||||
Debug.Console(1, this, "Phone is OffHook: {0}", Status.PhoneCall.OffHook);
|
||||
PhoneOffHookFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void SetUpDirectory()
|
||||
@@ -477,9 +580,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCodecCommDebug", "0 for Off, 1 for on",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"),
|
||||
"GetZoomRoomContacts", "Triggers a refresh of the codec phonebook",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
if (!_props.DisablePhonebookAutoDownload)
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"),
|
||||
"GetZoomRoomContacts", "Triggers a refresh of the codec phonebook",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
|
||||
"Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
@@ -624,8 +731,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
// zCommand
|
||||
|
||||
_syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 512");
|
||||
if (!_props.DisablePhonebookAutoDownload)
|
||||
{
|
||||
_syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 512");
|
||||
}
|
||||
|
||||
_syncState.AddQueryToQueue("zCommand Bookings List");
|
||||
_syncState.AddQueryToQueue("zCommand Call ListParticipants");
|
||||
_syncState.AddQueryToQueue("zCommand Call Info");
|
||||
|
||||
|
||||
_syncState.StartSync();
|
||||
@@ -638,6 +751,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
private void ProcessMessage(string message)
|
||||
{
|
||||
// Counts the curly braces
|
||||
if (message.Contains("client_loop: send disconnect: Broken pipe"))
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Zoom Room Controller or App connected. Essentials will NOT control the Zoom Room until it is disconnected.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.Contains('{'))
|
||||
{
|
||||
_jsonCurlyBraceCounter++;
|
||||
@@ -726,6 +847,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Thread.Sleep(100);
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list");
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (!_props.DisablePhonebookAutoDownload)
|
||||
{
|
||||
SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact");
|
||||
}
|
||||
// switch to json format
|
||||
SendText("format json");
|
||||
});
|
||||
@@ -804,6 +930,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
switch (topKey.ToLower())
|
||||
{
|
||||
case "inforesult":
|
||||
{
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Info);
|
||||
break;
|
||||
}
|
||||
case "phonebooklistresult":
|
||||
{
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook);
|
||||
@@ -843,7 +974,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
// this is a single participant event notification
|
||||
|
||||
var participant =
|
||||
JsonConvert.DeserializeObject<zCommand.ListParticipant>(responseObj.ToString());
|
||||
JsonConvert.DeserializeObject<zCommand.ListParticipant>(
|
||||
responseObj.ToString());
|
||||
|
||||
if (participant != null)
|
||||
{
|
||||
@@ -953,13 +1085,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
break;
|
||||
}
|
||||
case "bookings":
|
||||
case "bookings updated":
|
||||
{
|
||||
// Bookings have been updated, trigger a query to retreive the new bookings
|
||||
if (responseObj["Updated"] != null)
|
||||
{
|
||||
GetBookings();
|
||||
}
|
||||
GetBookings();
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -967,6 +1095,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing);
|
||||
|
||||
SetLayout();
|
||||
|
||||
break;
|
||||
}
|
||||
case "incomingcallindication":
|
||||
@@ -1079,6 +1209,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
break;
|
||||
}
|
||||
case "phonecallstatus":
|
||||
{
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -1190,6 +1325,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLayout()
|
||||
{
|
||||
if (!_props.AutoDefaultLayouts) return;
|
||||
|
||||
if (
|
||||
(Status.Call.Sharing.State == zEvent.eSharingState.Receiving ||
|
||||
Status.Call.Sharing.State == zEvent.eSharingState.Sending))
|
||||
{
|
||||
SendText(String.Format("zconfiguration call layout style: {0}",
|
||||
_props.DefaultSharingLayout));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendText(String.Format("zconfiguration call layout style: {0}",
|
||||
_props.DefaultCallLayout));
|
||||
}
|
||||
}
|
||||
|
||||
public void PrintCurrentCallParticipants()
|
||||
{
|
||||
if (Debug.Level <= 0)
|
||||
@@ -1228,13 +1381,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
if (callStatus != zStatus.eCallStatus.IN_MEETING || callStatus != zStatus.eCallStatus.CONNECTING_MEETING)
|
||||
{
|
||||
Status.Call = new zStatus.Call {Status = callStatus};
|
||||
|
||||
SetUpCallFeedbackActions();
|
||||
}
|
||||
|
||||
if (ActiveCalls.Count == 0)
|
||||
{
|
||||
if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING)
|
||||
if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING ||
|
||||
callStatus == zStatus.eCallStatus.IN_MEETING)
|
||||
{
|
||||
var newCall = new CodecActiveCallItem {Status = eCodecCallStatus.Connecting};
|
||||
var newStatus = eCodecCallStatus.Unknown;
|
||||
|
||||
switch (callStatus)
|
||||
{
|
||||
case zStatus.eCallStatus.CONNECTING_MEETING:
|
||||
newStatus = eCodecCallStatus.Connecting;
|
||||
break;
|
||||
case zStatus.eCallStatus.IN_MEETING:
|
||||
newStatus = eCodecCallStatus.Connected;
|
||||
break;
|
||||
}
|
||||
|
||||
var newCall = new CodecActiveCallItem {Status = newStatus};
|
||||
|
||||
ActiveCalls.Add(newCall);
|
||||
|
||||
@@ -1279,13 +1447,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
ActiveCalls.Remove(call);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "**************************************************************************");
|
||||
|
||||
//clear participants list after call cleanup
|
||||
if (ActiveCalls.Count == 0)
|
||||
{
|
||||
Participants.CurrentParticipants = new List<Participant>();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCallStatusChange(CodecActiveCallItem item)
|
||||
{
|
||||
base.OnCallStatusChange(item);
|
||||
|
||||
if (_props.AutoDefaultLayouts)
|
||||
{
|
||||
SetLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public override void StartSharing()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
SendText("zCommand Call Sharing HDMI Start");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1343,7 +1526,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Increments the voluem
|
||||
/// </summary>
|
||||
@@ -1486,7 +1668,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public override void SendDtmf(string s)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
SendDtmfToPhone(s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1553,6 +1735,115 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public CodecParticipants Participants { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IHasCameraOff
|
||||
|
||||
public BoolFeedback CameraIsOffFeedback { get; private set; }
|
||||
|
||||
public void CameraOff()
|
||||
{
|
||||
SendText("zConfiguration Call Camera Mute: On");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IHasCameraAutoMode
|
||||
|
||||
//Zoom doesn't support camera auto modes. Setting this to just unmute video
|
||||
public void CameraAutoModeOn()
|
||||
{
|
||||
throw new NotImplementedException("Zoom Room Doesn't support camera auto mode");
|
||||
}
|
||||
|
||||
//Zoom doesn't support camera auto modes. Setting this to just unmute video
|
||||
public void CameraAutoModeOff()
|
||||
{
|
||||
SendText("zConfiguration Call Camera Mute: Off");
|
||||
}
|
||||
|
||||
public void CameraAutoModeToggle()
|
||||
{
|
||||
throw new NotImplementedException("Zoom Room doesn't support camera auto mode");
|
||||
}
|
||||
|
||||
public BoolFeedback CameraAutoModeIsOnFeedback { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IHasFarEndContentStatus
|
||||
|
||||
public BoolFeedback ReceivingContent { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IHasSelfviewPosition
|
||||
|
||||
private CodecCommandWithLabel _currentSelfviewPipPosition;
|
||||
|
||||
public StringFeedback SelfviewPipPositionFeedback { get; private set; }
|
||||
|
||||
public void SelfviewPipPositionSet(CodecCommandWithLabel position)
|
||||
{
|
||||
SendText(String.Format("zConfiguration Call Layout Position: {0}", position.Command));
|
||||
}
|
||||
|
||||
public void SelfviewPipPositionToggle()
|
||||
{
|
||||
if (_currentSelfviewPipPosition != null)
|
||||
{
|
||||
var nextPipPositionIndex = SelfviewPipPositions.IndexOf(_currentSelfviewPipPosition) + 1;
|
||||
|
||||
if (nextPipPositionIndex >= SelfviewPipPositions.Count)
|
||||
// Check if we need to loop back to the first item in the list
|
||||
nextPipPositionIndex = 0;
|
||||
|
||||
SelfviewPipPositionSet(SelfviewPipPositions[nextPipPositionIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
public List<CodecCommandWithLabel> SelfviewPipPositions = new List<CodecCommandWithLabel>()
|
||||
{
|
||||
new CodecCommandWithLabel("UpLeft", "Center Left"),
|
||||
new CodecCommandWithLabel("UpRight", "Center Right"),
|
||||
new CodecCommandWithLabel("DownRight", "Lower Right"),
|
||||
new CodecCommandWithLabel("DownLeft", "Lower Left")
|
||||
};
|
||||
|
||||
private void ComputeSelfviewPipStatus()
|
||||
{
|
||||
_currentSelfviewPipPosition =
|
||||
SelfviewPipPositions.FirstOrDefault(
|
||||
p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower()));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IHasPhoneDialing
|
||||
|
||||
private Func<bool> PhoneOffHookFeedbackFunc {get {return () => Status.PhoneCall.OffHook; }}
|
||||
private Func<string> CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } }
|
||||
private Func<string> CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } }
|
||||
|
||||
public BoolFeedback PhoneOffHookFeedback { get; private set; }
|
||||
public StringFeedback CallerIdNameFeedback { get; private set; }
|
||||
public StringFeedback CallerIdNumberFeedback { get; private set; }
|
||||
|
||||
public void DialPhoneCall(string number)
|
||||
{
|
||||
SendText(String.Format("zCommand Dial PhoneCallOut Number: {0}", number));
|
||||
}
|
||||
|
||||
public void EndPhoneCall()
|
||||
{
|
||||
SendText(String.Format("zCommand Dial PhoneHangUp CallId: {0}", Status.PhoneCall.CallId));
|
||||
}
|
||||
|
||||
public void SendDtmfToPhone(string digit)
|
||||
{
|
||||
SendText(String.Format("zCommand SendSipDTMF CallId: {0} Key: {1}", Status.PhoneCall.CallId, digit));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -68,7 +68,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
/// <summary>
|
||||
/// Builds the command and triggers the parent ZoomRoom to send it
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="state"></param>
|
||||
/// <param name="action"></param>
|
||||
void SendCommand(eZoomRoomCameraState state, eZoomRoomCameraAction action)
|
||||
@@ -79,23 +78,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
void StartContinueTimer()
|
||||
{
|
||||
if(ContinueTimer == null)
|
||||
ContinueTimer = new CTimer((o) => SendContinueAction(LastAction), ContinueTime);
|
||||
if (ContinueTimer == null)
|
||||
ContinueTimer = new CTimer((o) => SendContinueAction(LastAction), null, ContinueTime, ContinueTime);
|
||||
}
|
||||
|
||||
void SendContinueAction(eZoomRoomCameraAction action)
|
||||
{
|
||||
SendCommand(eZoomRoomCameraState.Continue, action);
|
||||
ContinueTimer.Reset();
|
||||
}
|
||||
|
||||
void StopContinueTimer()
|
||||
{
|
||||
if (ContinueTimer != null)
|
||||
if (ContinueTimer == null)
|
||||
{
|
||||
ContinueTimer.Stop();
|
||||
ContinueTimer.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
ContinueTimer.Stop();
|
||||
ContinueTimer.Dispose();
|
||||
ContinueTimer = null;
|
||||
}
|
||||
|
||||
#region IHasCameraPtzControl Members
|
||||
@@ -111,22 +112,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public void PanLeft()
|
||||
{
|
||||
if (!isMoving)
|
||||
if (isMoving)
|
||||
{
|
||||
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Left);
|
||||
StartContinueTimer();
|
||||
isPanning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Left);
|
||||
StartContinueTimer();
|
||||
isPanning = true;
|
||||
}
|
||||
|
||||
public void PanRight()
|
||||
{
|
||||
if (!isMoving)
|
||||
if (isMoving)
|
||||
{
|
||||
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Right);
|
||||
StartContinueTimer();
|
||||
isPanning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
SendCommand(eZoomRoomCameraState.Start, eZoomRoomCameraAction.Right);
|
||||
StartContinueTimer();
|
||||
isPanning = true;
|
||||
}
|
||||
|
||||
public void PanStop()
|
||||
|
||||
@@ -12,5 +12,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public class ZoomRoomPropertiesConfig
|
||||
{
|
||||
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
||||
|
||||
public bool DisablePhonebookAutoDownload { get; set; }
|
||||
public bool SupportsCameraAutoMode { get; set; }
|
||||
public bool SupportsCameraOff { get; set; }
|
||||
|
||||
//if true, the layouts will be set automatically when sharing starts/ends or a call is joined
|
||||
public bool AutoDefaultLayouts { get; set; }
|
||||
|
||||
/* This layout will be selected when Sharing starts (either from Far end or locally)*/
|
||||
public string DefaultSharingLayout { get; set; }
|
||||
|
||||
//This layout will be selected when a call is connected and no content is being shared
|
||||
public string DefaultCallLayout { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user