mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-31 13:25:00 +00:00
Compare commits
25 Commits
1.9.2-alph
...
1.9.2-rc-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c306e2c1a1 | ||
|
|
82af1366df | ||
|
|
56492a00cd | ||
|
|
8404e7d5a4 | ||
|
|
e4135a958c | ||
|
|
f4ac4e6319 | ||
|
|
b026174cd2 | ||
|
|
66ff6b2e07 | ||
|
|
e7bbfbd40a | ||
|
|
eec86fde48 | ||
|
|
7b57ce439e | ||
|
|
28bac18667 | ||
|
|
ea254ef983 | ||
|
|
76e4d4a82d | ||
|
|
4bd777f6b9 | ||
|
|
f607394ee7 | ||
|
|
085a64c87b | ||
|
|
5d120391a5 | ||
|
|
290e887903 | ||
|
|
de7a74eaff | ||
|
|
88e5c49663 | ||
|
|
1415999d86 | ||
|
|
db5aa319ec | ||
|
|
5f6b650dba | ||
|
|
4cc40227fd |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -7,6 +7,9 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Was this bug identified in a specific build version?**
|
||||
Please note the build version where this bug was identified
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
||||
@@ -450,14 +450,13 @@ namespace PepperDash.Essentials
|
||||
return;
|
||||
}
|
||||
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
|
||||
{
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
|
||||
if (room != null)
|
||||
{
|
||||
// default IPID
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
// default to no join map key
|
||||
string fusionJoinMapKey = string.Empty;
|
||||
|
||||
@@ -478,7 +477,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
|
||||
@@ -490,7 +489,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
@@ -502,7 +501,7 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
|
||||
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
@@ -515,9 +514,13 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
}
|
||||
|
||||
fusionIpId += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
|
||||
@@ -144,7 +144,6 @@
|
||||
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsTechRoomConfig.cs" />
|
||||
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
|
||||
<Compile Include="Room\Types\EssentialsCombinedHuddleVtc1Room.cs" />
|
||||
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
|
||||
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
|
||||
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||
|
||||
@@ -1,817 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsCombinedHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
|
||||
{
|
||||
private bool _codecExternalSourceChange;
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
|
||||
//************************
|
||||
// Call-related stuff
|
||||
|
||||
public BoolFeedback InCallFeedback { get; private set; }
|
||||
|
||||
///// <summary>
|
||||
///// Make this more specific
|
||||
///// </summary>
|
||||
//public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||
/// </summary>
|
||||
public IntFeedback CallTypeFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// When something in the room is sharing with the far end or through other means
|
||||
/// </summary>
|
||||
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||
|
||||
//************************
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
var val = CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||
&& disp != null;
|
||||
//&& disp.PowerIsOnFeedback.BoolValue;
|
||||
return val;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsCoolingDownFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
private List<IRoutingSinkWithSwitching> Displays;
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
|
||||
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||
|
||||
public VideoCodecBase VideoCodec { get; private set; }
|
||||
|
||||
public AudioCodecBase AudioCodec { get; private set; }
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
public ushort DefaultVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||
/// tag to device.
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _CurrentSourceInfo; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
// add to in-use tracking
|
||||
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
|
||||
var vc = VideoCodec as IHasExternalSourceSwitching;
|
||||
if (vc != null && !_codecExternalSourceChange)
|
||||
{
|
||||
vc.SetSelectedSource(CurrentSourceInfoKey);
|
||||
}
|
||||
|
||||
_codecExternalSourceChange = false;
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "codecOsd"
|
||||
/// </summary>
|
||||
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||
|
||||
/// <summary>
|
||||
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||
/// always returns the VideoCodec if it is capable
|
||||
/// </summary>
|
||||
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||
|
||||
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||
|
||||
public EssentialsCombinedHuddleVtc1Room(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsConferenceRoomPropertiesConfig>
|
||||
(config.Properties.ToString());
|
||||
|
||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||
|
||||
|
||||
if (VideoCodec == null)
|
||||
throw new ArgumentNullException("codec cannot be null");
|
||||
|
||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||
if (AudioCodec == null)
|
||||
Debug.Console(0, this, "No Audio Codec Found");
|
||||
|
||||
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error building room: \n{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
|
||||
// Combines call feedback from both codecs if available
|
||||
InCallFeedback = new BoolFeedback(() =>
|
||||
{
|
||||
bool inAudioCall = false;
|
||||
bool inVideoCall = false;
|
||||
|
||||
if (AudioCodec != null)
|
||||
inAudioCall = AudioCodec.IsInCall;
|
||||
|
||||
if (VideoCodec != null)
|
||||
inVideoCall = VideoCodec.IsInCall;
|
||||
|
||||
if (inAudioCall || inVideoCall)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
SetupDisplays();
|
||||
|
||||
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
|
||||
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||
|
||||
// Get emergency object, if any
|
||||
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||
|
||||
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||
|
||||
|
||||
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
|
||||
|
||||
if (AudioCodec != null)
|
||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
|
||||
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||
|
||||
// link privacy to VC (for now?)
|
||||
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SetSourceListKey();
|
||||
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "Error Initializing Room: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupDisplays()
|
||||
{
|
||||
//DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
SetCodecExternalSources();
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsConferenceRoomPropertiesConfig>(config.Properties.ToString());
|
||||
|
||||
if (newPropertiesConfig != null)
|
||||
PropertiesConfig = newPropertiesConfig;
|
||||
|
||||
ConfigWriter.UpdateRoomConfig(config);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Add Occupancy object from config
|
||||
if (PropertiesConfig.Occupancy != null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
|
||||
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||
}
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override void EndShutdown()
|
||||
{
|
||||
VideoCodec.EndAllCalls();
|
||||
|
||||
SetDefaultLevels();
|
||||
|
||||
RunDefaultPresentRoute();
|
||||
|
||||
CrestronEnvironment.Sleep(1000);
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||
|
||||
RunRouteAction("roomOff");
|
||||
VideoCodec.StopSharing();
|
||||
VideoCodec.StandbyActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Routes the default source item, if any. Returns true when default route exists
|
||||
/// </summary>
|
||||
public override bool RunDefaultPresentRoute()
|
||||
{
|
||||
if (DefaultSourceItem != null)
|
||||
RunRouteAction(DefaultSourceItem);
|
||||
|
||||
return DefaultSourceItem != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the room when started into call mode without presenting a source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool RunDefaultCallRoute()
|
||||
{
|
||||
RunRouteAction(DefaultCodecRouteString);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RunRouteActionCodec(string routeKey, string sourceListKey)
|
||||
{
|
||||
_codecExternalSourceChange = true;
|
||||
RunRouteAction(routeKey, sourceListKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
public void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="souceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
Debug.Console(1, this, "No sourceListKey present. RunRouteAction assumes default source list.");
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
/// <param name="souceListKey"></param>
|
||||
/// <param name="successCallback"></param>
|
||||
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
RunRouteAction(routeKey, successCallback);
|
||||
}
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void RunRouteAction(string routeKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
{
|
||||
// try to prevent multiple simultaneous selections
|
||||
SourceSelectLock.TryEnter();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||
if (dict == null)
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get the list item by it's string key
|
||||
if (!dict.ContainsKey(routeKey))
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||
routeKey, SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// End usage timer on last source
|
||||
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||
{
|
||||
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// There MAY have been failures in here. Protect
|
||||
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let's run it
|
||||
var item = dict[routeKey];
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
|
||||
LastSourceKey = routeKey;
|
||||
}
|
||||
else
|
||||
CurrentSourceInfoKey = null;
|
||||
|
||||
// hand off the individual routes to this helper
|
||||
foreach (var route in item.RouteList)
|
||||
DoRouteItem(route);
|
||||
|
||||
// Start usage timer on routed source
|
||||
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||
{
|
||||
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||
}
|
||||
|
||||
// See if this can be moved into common, base-class method -------------
|
||||
|
||||
|
||||
// Set volume control, using default if non provided
|
||||
IBasicVolumeControls volDev = null;
|
||||
// Handle special cases for volume control
|
||||
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||
volDev = DefaultVolumeControls;
|
||||
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||
// Or a specific device, probably rarely used.
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||
if (dev is IBasicVolumeControls)
|
||||
volDev = dev as IBasicVolumeControls;
|
||||
else if (dev is IHasVolumeDevice)
|
||||
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
|
||||
if (volDev != CurrentVolumeControls)
|
||||
{
|
||||
// zero the volume on the device we are leaving.
|
||||
// Set the volume to default on device we are entering
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
|
||||
vd.SetVolume(0);
|
||||
}
|
||||
|
||||
CurrentVolumeControls = volDev;
|
||||
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||
{
|
||||
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||
vd.SetVolume(vol);
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// store the name and UI info for routes
|
||||
if (item.SourceKey == "$off")
|
||||
{
|
||||
CurrentSourceInfoKey = routeKey;
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
else if (item.SourceKey != null)
|
||||
{
|
||||
CurrentSourceInfoKey = routeKey;
|
||||
CurrentSourceInfo = item;
|
||||
}
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
if (OnFeedback.BoolValue)
|
||||
{
|
||||
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
|
||||
{
|
||||
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
|
||||
VideoCodec.StandbyDeactivate();
|
||||
}
|
||||
|
||||
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
|
||||
{
|
||||
VideoCodec.StandbyDeactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
|
||||
}
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||
}
|
||||
|
||||
SourceSelectLock.Leave();
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
void DoRouteItem(SourceRouteListItem route)
|
||||
{
|
||||
// if there is a $defaultAll on route, run two separate
|
||||
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Going to assume a single-path route for now
|
||||
var tempVideo = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultDisplay",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Video
|
||||
};
|
||||
DoRoute(tempVideo);
|
||||
}
|
||||
else
|
||||
DoRoute(route);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultDisplay;
|
||||
else
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||
if (source == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
//Implement this
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does what it says
|
||||
/// </summary>
|
||||
public override void SetDefaultLevels()
|
||||
{
|
||||
Debug.Console(1, this, "Restoring default levels");
|
||||
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||
if (vc != null)
|
||||
vc.SetVolume(DefaultVolume);
|
||||
}
|
||||
/// <summary>
|
||||
/// Will power the room on with the last-used source
|
||||
/// </summary>
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||
/// </summary>
|
||||
private void SetCodecExternalSources()
|
||||
{
|
||||
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||
|
||||
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Get the tie line that the external switcher is connected to
|
||||
string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
|
||||
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
|
||||
|
||||
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
|
||||
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
|
||||
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||
{
|
||||
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCodecBranding()
|
||||
{
|
||||
var vcWithBranding = VideoCodec as IHasBranding;
|
||||
|
||||
if (vcWithBranding == null) return;
|
||||
|
||||
Debug.Console(1, this, "Setting Codec Branding");
|
||||
vcWithBranding.InitializeBranding(Key);
|
||||
}
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
|
||||
public void PrivacyModeOff()
|
||||
{
|
||||
VideoCodec.PrivacyModeOff();
|
||||
}
|
||||
|
||||
public void PrivacyModeOn()
|
||||
{
|
||||
VideoCodec.PrivacyModeOn();
|
||||
}
|
||||
|
||||
public void PrivacyModeToggle()
|
||||
{
|
||||
VideoCodec.PrivacyModeToggle();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||
@@ -210,7 +210,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
|
||||
(config.Properties.ToString());
|
||||
DefaultDisplay = DeviceManager.GetDeviceForKey((PropertiesConfig as EssentialsHuddleVtc1PropertiesConfig).DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||
|
||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PepperDash.Essentials
|
||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||
{
|
||||
EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; }
|
||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||
|
||||
void RunRouteAction(string routeKey);
|
||||
|
||||
|
||||
@@ -79,6 +79,16 @@ namespace PepperDash.Essentials
|
||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||
else if (type == "tsw1060")
|
||||
Panel = new Tsw1060(id, Global.ControlSystem);
|
||||
else if (type == "tsw570")
|
||||
Panel = new Tsw570(id, Global.ControlSystem);
|
||||
else if (type == "tsw770")
|
||||
Panel = new Tsw770(id, Global.ControlSystem);
|
||||
else if (type == "ts770")
|
||||
Panel = new Ts770(id, Global.ControlSystem);
|
||||
else if (type == "tsw1070")
|
||||
Panel = new Tsw1070(id, Global.ControlSystem);
|
||||
else if (type == "ts1070")
|
||||
Panel = new Ts1070(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
@@ -203,7 +213,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
public EssentialsTouchpanelControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" };
|
||||
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
|
||||
@@ -207,6 +207,7 @@ namespace PepperDash.Essentials
|
||||
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
||||
|
||||
// Set the call status text
|
||||
Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count);
|
||||
if (codec.ActiveCalls.Count > 0)
|
||||
{
|
||||
if (codec.ActiveCalls.Count == 1)
|
||||
|
||||
@@ -1035,7 +1035,7 @@ namespace PepperDash.Essentials
|
||||
if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing)
|
||||
{
|
||||
Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source");
|
||||
CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey);
|
||||
CurrentRoom.RunRouteAction("codecOsd");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace PepperDash.Essentials.Core
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
Debug.Console(0,"****PreActivation starting...****");
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
@@ -69,9 +70,12 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} PreActivation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "****PreActivation complete****");
|
||||
Debug.Console(0, "****Activation starting...****");
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
@@ -83,10 +87,14 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} Activation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "****Activation complete****");
|
||||
Debug.Console(0, "****PostActivation starting...****");
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
@@ -97,10 +105,13 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
Debug.Console(0, d, "ERROR: Device {1} PostActivation failure: {0}", e.Message, d.Key);
|
||||
Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, "****PostActivation complete****");
|
||||
|
||||
OnAllDevicesActivated();
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -19,13 +19,34 @@ namespace PepperDash.Essentials.Core
|
||||
protected EssentialsDevice(string key)
|
||||
: base(key)
|
||||
{
|
||||
|
||||
SubscribeToActivateComplete();
|
||||
}
|
||||
|
||||
protected EssentialsDevice(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
SubscribeToActivateComplete();
|
||||
}
|
||||
|
||||
private void SubscribeToActivateComplete()
|
||||
{
|
||||
DeviceManager.AllDevicesActivated += DeviceManagerOnAllDevicesActivated;
|
||||
}
|
||||
|
||||
private void DeviceManagerOnAllDevicesActivated(object sender, EventArgs eventArgs)
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Exception initializing device: {0}", ex.Message);
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,9 +119,21 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
var slot = Global.ControlSystem.ProgramNumber;
|
||||
|
||||
var guidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId);
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
var oldGuidFilePath = Global.FilePathPrefix +
|
||||
string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag);
|
||||
|
||||
if (File.Exists(oldGuidFilePath))
|
||||
{
|
||||
Debug.Console(0, this, "Migrating from old Fusion GUID file to new Fusion GUID File");
|
||||
|
||||
File.Copy(oldGuidFilePath, guidFilePath);
|
||||
|
||||
File.Delete(oldGuidFilePath);
|
||||
}
|
||||
|
||||
_guidFileExists = File.Exists(guidFilePath);
|
||||
|
||||
// Check if file exists
|
||||
if (!_guidFileExists)
|
||||
@@ -149,19 +161,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
});
|
||||
AddPostActivationAction(() => PostActivate(guidFilePath));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -169,6 +169,20 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
}
|
||||
}
|
||||
|
||||
private void PostActivate(string guidFilePath)
|
||||
{
|
||||
CreateSymbolAndBasicSigs(_ipId);
|
||||
SetUpSources();
|
||||
SetUpCommunitcationMonitors();
|
||||
SetUpDisplay();
|
||||
SetUpError();
|
||||
ExecuteCustomSteps();
|
||||
|
||||
FusionRVI.GenerateFileForAllFusionDevices();
|
||||
|
||||
GenerateGuidFile(guidFilePath);
|
||||
}
|
||||
|
||||
protected string RoomGuid
|
||||
{
|
||||
get { return _guiDs.RoomGuid; }
|
||||
@@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
|
||||
protected virtual void CreateSymbolAndBasicSigs(uint ipId)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||
|
||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||
|
||||
@@ -88,11 +88,6 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
else
|
||||
Debug.Console(0, this, "Unable to add Red LED device");
|
||||
|
||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
};
|
||||
|
||||
AddPostActivationAction(() => {
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||
@@ -103,6 +98,15 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SetPrivacyDevice(IPrivacy privacyDevice)
|
||||
{
|
||||
PrivacyDevice = privacyDevice;
|
||||
|
||||
@@ -39,10 +39,10 @@ namespace PepperDash.Essentials.Core
|
||||
RegisterCrestronGenericBase(_partitionSensor);
|
||||
|
||||
NameFeedback = new StringFeedback(() => Name);
|
||||
EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue);
|
||||
PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||
PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||
SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue);
|
||||
EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue);
|
||||
PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue);
|
||||
PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue);
|
||||
SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue);
|
||||
|
||||
if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent;
|
||||
});
|
||||
@@ -93,6 +93,9 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestEnableFeedback = state;
|
||||
|
||||
EnableFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString());
|
||||
return;
|
||||
}
|
||||
@@ -105,6 +108,10 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestPartitionSensedFeedback = state;
|
||||
|
||||
PartitionPresentFeedback.FireUpdate();
|
||||
PartitionNotSensedFeedback.FireUpdate();
|
||||
|
||||
Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString());
|
||||
return;
|
||||
}
|
||||
@@ -117,6 +124,8 @@ namespace PepperDash.Essentials.Core
|
||||
if (InTestMode)
|
||||
{
|
||||
TestSensitivityFeedback = value;
|
||||
|
||||
SensitivityFeedback.FireUpdate();
|
||||
Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
void CreateScenarios()
|
||||
{
|
||||
RoomCombinationScenarios = new List<IRoomCombinationScenario>();
|
||||
|
||||
foreach (var scenarioConfig in _propertiesConfig.Scenarios)
|
||||
{
|
||||
var scenario = new RoomCombinationScenario(scenarioConfig);
|
||||
|
||||
@@ -87,9 +87,6 @@ namespace PepperDash.Essentials.Core
|
||||
[JsonProperty("partitionStates")]
|
||||
public List<PartitionState> PartitionStates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines which UI devices get mapped to which room in this scenario. The Key should be the key of the UI device and the Value should be the key of the room to map to
|
||||
/// </summary>
|
||||
[JsonProperty("uiMap")]
|
||||
public Dictionary<string, string> UiMap { get; set; }
|
||||
|
||||
|
||||
@@ -550,6 +550,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(GetBookings, "GetCodecBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
var socket = Communication as ISocketStatus;
|
||||
if (socket != null)
|
||||
{
|
||||
@@ -558,9 +565,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
|
||||
Communication.Connect();
|
||||
|
||||
CommunicationMonitor.Start();
|
||||
CommunicationMonitor.Start();
|
||||
|
||||
string prefix = "xFeedback register ";
|
||||
const string prefix = "xFeedback register ";
|
||||
|
||||
CliFeedbackRegistrationExpression =
|
||||
prefix + "/Configuration" + Delimiter +
|
||||
@@ -575,14 +582,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
prefix + "/Status/Video/Layout" + Delimiter +
|
||||
prefix + "/Status/Video/Input/MainVideoMute" + Delimiter +
|
||||
prefix + "/Bookings" + Delimiter +
|
||||
prefix + "/Event/CallDisconnect" + Delimiter +
|
||||
prefix + "/Event/CallDisconnect" + Delimiter +
|
||||
prefix + "/Event/Bookings" + Delimiter +
|
||||
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
|
||||
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
||||
|
||||
return base.CustomActivate();
|
||||
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc.
|
||||
/// </summary>
|
||||
|
||||
@@ -667,6 +667,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
DirectoryRoot = new CodecDirectory();
|
||||
|
||||
_currentDirectoryResult = DirectoryRoot;
|
||||
|
||||
DirectoryBrowseHistory = new List<CodecDirectory>();
|
||||
DirectoryBrowseHistoryStack = new Stack<CodecDirectory>();
|
||||
|
||||
@@ -717,7 +719,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings",
|
||||
"Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
var socket = Communication as ISocketStatus;
|
||||
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
#region Overrides of Device
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
var socket = Communication as ISocketStatus;
|
||||
if (socket != null)
|
||||
{
|
||||
socket.ConnectionChange += socket_ConnectionChange;
|
||||
@@ -728,11 +739,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Communication.Connect();
|
||||
|
||||
CommunicationMonitor.Start();
|
||||
}
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void SetCommDebug(string s)
|
||||
public void SetCommDebug(string s)
|
||||
{
|
||||
if (s == "1")
|
||||
{
|
||||
@@ -970,10 +981,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
SendText("echo off");
|
||||
Thread.Sleep(100);
|
||||
// set feedback exclusions
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list");
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list");
|
||||
Thread.Sleep(100);
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list");
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list");
|
||||
Thread.Sleep(100);
|
||||
SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist");
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (!_props.DisablePhonebookAutoDownload)
|
||||
{
|
||||
@@ -1565,6 +1578,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Debug.Console(1, this, "Creating new Status.Call object");
|
||||
Status.Call = new zStatus.Call { Status = callStatus };
|
||||
|
||||
OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected });
|
||||
|
||||
SetUpCallFeedbackActions();
|
||||
}
|
||||
|
||||
@@ -1585,7 +1600,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
|
||||
var newCall = new CodecActiveCallItem { Status = newStatus };
|
||||
var newCall = new CodecActiveCallItem
|
||||
{
|
||||
Name = Status.Call.Info.meeting_list_item.meetingName,
|
||||
Id = Status.Call.Info.meeting_id,
|
||||
Status = newStatus
|
||||
};
|
||||
|
||||
ActiveCalls.Add(newCall);
|
||||
|
||||
@@ -1594,6 +1614,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
OnCallStatusChange(newCall);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1641,7 +1663,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
//clear participants list after call cleanup
|
||||
if (ActiveCalls.Count == 0)
|
||||
{
|
||||
Participants.CurrentParticipants = new List<Participant>();
|
||||
var emptyList = new List<Participant>();
|
||||
Participants.CurrentParticipants = emptyList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<packages>
|
||||
<package id="PepperDashCore" version="1.0.47" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
|
||||
<package id="PepperDashCore" version="1.0.48" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
|
||||
</packages>
|
||||
Reference in New Issue
Block a user