Compare commits

..

56 Commits

Author SHA1 Message Date
Neil Dorin
eec86fde48 Updates incorrect path for ZoomRoom feedback exclusions and adds toll_free_callinList 2021-07-28 15:23:57 -06:00
Neil Dorin
7b57ce439e #761 Adds support for x70 series touchpanels 2021-07-28 14:47:17 -06:00
Andrew Welker
5d120391a5 Merge pull request #752 from PepperDash/feature/ndorin-patch-1
Adds a prompt to capture affected version
2021-07-21 13:16:59 -06:00
Neil Dorin
db5aa319ec Adds a prompt to capture affected version 2021-07-20 16:49:03 -06:00
Andrew Welker
4cc40227fd Merge pull request #734 from PepperDash/hotfix/zip-release-upload
ci: Remove condition on upload to release
2021-07-08 11:41:32 -06:00
Andrew Welker
d0dbbe095f ci: Remove condition on upload to release 2021-07-08 11:16:41 -06:00
Neil Dorin
e6ecaf3a1e Merge pull request #726 from PepperDash/hotfix/add-eisc-server-client-options-to-eiscapiadvanced-factory
adds new type options to use EISCClient and EISCServer in eiscapiadvanced
2021-06-24 16:35:18 -06:00
Neil Dorin
5c9996e728 adds new type options to use EISCClient and EISCServer in eiscapiadvanced 2021-06-17 13:49:09 -06:00
Andrew Welker
8fadfa98f2 Merge pull request #724 from PepperDash/hotfix/zoom-room-views
Hotfix/zoom room views
2021-06-17 10:02:17 -06:00
Andrew Welker
1ccf54003f Merge branch 'main' into hotfix/zoom-room-views 2021-06-17 09:32:04 -06:00
Andrew Welker
319d8f99c5 Merge pull request #721 from PepperDash/hotfix/plugin-loading
adds check for abstract class before attempting to create instance
2021-06-16 15:17:32 -06:00
Neil Dorin
cc742f4291 adds check for abstract class before attempting to create instance 2021-06-16 13:11:45 -06:00
Jason DeVito
6beff106ec Updated packages.config to track latest PepperDash Core release. Updated ZoomRoom LinkZoomRoomToApi to update the bridge when it comes online. 2021-06-10 17:45:23 -05:00
Neil Dorin
cb35aa13f5 lets it fall through conditions to fire the ParticipantsChanged event if an already pinned participant is found 2021-06-09 17:55:55 -06:00
Neil Dorin
b71523bd2d Adds condition to not check for already pinned participant if incoming message has user id < 0 2021-06-09 17:38:50 -06:00
Neil Dorin
0c56da112c Changes to respond to new pinned participant message by clearing out already pinned participant fb first. 2021-06-09 17:07:25 -06:00
Neil Dorin
08f4d8e9a2 Attempts to unpin participant from same screenIndex if one is already pinned. 2021-06-09 16:57:42 -06:00
Neil Dorin
25e7e9634a updates PD Core version to include xsig token fixes 2021-06-09 16:56:56 -06:00
Neil Dorin
7ac3f81ea5 Initialize SreenIndexIsPinnedToFb to -1. Adds debugging for xsig tokens 2021-06-09 16:14:18 -06:00
Neil Dorin
1c06e8381b Fixed inverted video mute FB and adds debug statements to help see participant pin status 2021-06-09 13:30:36 -06:00
Jason DeVito
f5305197b3 Updates to LinkZoomRoomApi method 2021-06-09 13:37:01 -05:00
Jason DeVito
1805ebaf0f Converted ZoomRoom Layout Size properties and methods to interface, IHasSelfviewSize, following the patterns implemented for IHasSelfviewPosition and SelfviewPipPosition. 2021-06-08 17:56:00 -05:00
Jason DeVito
ca8207f2bd Removed Layout Position properties and methods. Using SelfviewPipPosition properties and methods. 2021-06-08 15:20:42 -05:00
Jason DeVito
655bb954fa Updated IHasCodecLayouts and ZoomRoom to test feedback of Layout Size and Layout Position. 2021-06-08 14:38:33 -05:00
Jason DeVito
492e593263 Updated IHasCodecLayouts to implement Layout Position selection and feedback, updated bridge map to map Layout Position signals. Updated ZoomRoom to implement Layout Position selection and feedback. 2021-06-07 22:22:00 -05:00
Jason DeVito
afe2046c81 Added methods to select Call Layout Size. 2021-06-07 14:45:40 -05:00
Neil Dorin
98d3a4a2fa Merge pull request #713 from PepperDash/release/1.9.0
1.9.0
2021-05-25 14:48:52 -06:00
Andrew Welker
1702c69b73 Merge branch 'main' into release/1.9.0 2021-05-25 14:37:27 -06:00
Andrew Welker
722d28b1b3 Merge pull request #710 from PepperDash/hotfix/techroom-preset-recall-event
Hotfix/techroom preset recall event
2021-05-24 13:32:46 -06:00
Andrew Welker
ef7da0d7af Merge branch 'development' into hotfix/techroom-preset-recall-event 2021-05-24 13:19:45 -06:00
Neil Dorin
77d8e63a31 Merge pull request #709 from PepperDash/hotfix/techroom-preset-recall-event
Hotfix/techroom preset recall event
2021-05-24 12:59:54 -06:00
Neil Dorin
d2d99d4bfa Merge branch 'main' into hotfix/techroom-preset-recall-event 2021-05-24 12:45:27 -06:00
Neil Dorin
4bd71b04bf Merge pull request #708 from PepperDash/feature/add-zoomroom-participant-actions
Feature/add zoomroom participant actions
2021-05-20 20:34:45 -06:00
Andrew Welker
c5bcd89695 Merge branch 'development' into feature/add-zoomroom-participant-actions 2021-05-20 18:34:58 -06:00
Jason DeVito
c7cc98bff7 Removed old TODO's from VideoCodecBase.cs. Marked TODO's for Issue #697. 2021-05-20 19:32:11 -05:00
Jason DeVito
db60f8f1be ResponseObject.cs updates: Added and tested SortParticipantListtByHandStatus method. Found an issue with HandStatus response, property names include ': ', updated JsonProperty definitions to account for issues with expected returns vs. actual returns. 2021-05-20 15:43:02 -05:00
Andrew Welker
e82efdde2d Merge pull request #707 from PepperDash/hotfix/devjson-overload-fix
fix:(EssentialsCore) Add ability for `devjson` command to handle overloads
2021-05-20 11:04:23 -06:00
Andrew Welker
d00c8bed5f fix:(EssentialsCore) Add ability for devjson command to handle overloads
The `devjson` command needs to ability to handle overloads. With this change, if a method is an overloaded method, the command will get all methods on an object that match the entered method name, then get the first entry in the list of methods that matches the length of the provided parameters list.

This won't work in all cases, as there may be situations where the parameters of the methods have the same length, but different types. In that situation, it's likely that the conversion from `Object` to the desired type will fail, in which case, the command will notify the user that something went wrong.
2021-05-20 10:52:12 -06:00
Andrew Welker
a91af6bd75 Merge pull request #703 from PepperDash/feature/add-rfi-issue-template
Adds RFI Template
2021-05-20 09:22:23 -06:00
Neil Dorin
2d36b80800 Adds CH5 option 2021-05-14 15:46:12 -06:00
Neil Dorin
e152b9a504 Merge branch 'development' into feature/add-rfi-issue-template 2021-05-14 15:05:25 -06:00
Neil Dorin
eac7c91327 Create rfi_request.md 2021-05-13 18:07:03 -06:00
Jason DeVito
ac0d5e59a0 ZoomRoom.cs, commented out Debug statement @ line 874 to remove 'JSON Curly Brace Count:' messages in console when using debug level 2. 2021-05-12 11:27:33 -05:00
Andrew Welker
78be8ec5f2 Merge pull request #701 from PepperDash/feature/reconfigurable-device-write-control
Feature/reconfigurable device write control
2021-05-11 20:22:04 -06:00
Jason Alborough
5fc4ff6027 #700 FIxes issue where ConfigWrite.UpdateDeviceConfig and UpdateRoomConfig do not write config to file 2021-05-11 20:28:15 -04:00
Neil Dorin
63853739f3 Updates object structure to deal with a bug in ZoomRoom 5.6.3 that responds with an incorrect object structure for the layout style property 2021-05-11 17:23:26 -06:00
Jason DeVito
c14193f9ac Updates to VideoCodecControllerJoinMap to fix joins for Participant triggers. Updated ZoomRoomJoinMaps to implement zConfiguration.eLayoutStyle to pass the name across the bridge. 2021-05-11 18:13:18 -05:00
Jason T Alborough
da179c01f5 Fixes UpdateDeviceConfig() 2021-05-11 17:52:26 -04:00
Jason Alborough
0ded3e30f9 Merge branch 'development' into feature/reconfigurable-device-write-control 2021-05-11 15:24:40 -04:00
Jason T Alborough
8d215930d9 Adds WriteControlProperty to ReconfigurableDevice
CameraBase now uses ReconfigurableDevice
2021-05-11 15:20:35 -04:00
Neil Dorin
b4edb021ee #698 merged in join map updates from JKD. Fixed enum bit comparison for available layout feedbacks 2021-05-11 12:23:27 -06:00
Neil Dorin
52caa98f33 Merge branch 'feature/add-zoomroom-layout-controls' into feature/add-zoomroom-participant-actions 2021-05-11 11:10:37 -06:00
Jason DeVito
4e041d1773 Removed unused DecodecParticipantsXSig method. 2021-05-11 11:36:17 -05:00
Neil Dorin
a06333e1c3 Adds temp join numbers for participant actions 2021-05-10 15:38:33 -06:00
Neil Dorin
d937dc14fc #698 Adds actions to toggle audio/video mute and pinning for participants 2021-05-10 15:09:33 -06:00
Neil Dorin
685c344785 #690 fixes incorrect conditional check before firing feedback 2021-04-20 14:38:24 -06:00
21 changed files with 4616 additions and 4072 deletions

View File

@@ -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.

27
.github/ISSUE_TEMPLATE/rfi_request.md vendored Normal file
View File

@@ -0,0 +1,27 @@
---
name: Request for Information
about: Request specific information about capabilities of the framework
title: "[RFI]-"
labels: RFI
assignees: ''
---
**What is your request?**
Please provide as much detail as possible.
**What is the intended use case**
- [ ] Essentials Standalone Application
- [ ] Essentials + SIMPL Windows Hybrid
**User Interface Requirements**
- [ ] Not Applicable (logic only)
- [ ] Crestron Smart Graphics Touchpanel
- [ ] Cisco Touch10
- [ ] Mobile Control
- [ ] Crestron CH5 Touchpanel interface
**Additional context**
Add any other context or screenshots about the request here.

View File

@@ -90,7 +90,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload the build package to the release
- name: Upload Release Package
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
id: upload_release
uses: actions/upload-release-asset@v1
with:

View File

@@ -107,14 +107,18 @@ namespace PepperDash.Essentials
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
{
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
if (!_currentPresets.ContainsKey(device.Key))
{
return;
}
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
_currentPresets[device.Key] = channel;
if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
if (CurrentPresetsFeedbacks.ContainsKey(device.Key))
{
CurrentPresetsFeedbacks[device.Key].FireUpdate();
}

View File

@@ -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)

View File

@@ -385,7 +385,7 @@ namespace PepperDash.Essentials.Core.Bridges
{
public EiscApiAdvancedFactory()
{
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "vceiscapiadv", "vceiscapiadvanced" };
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -403,6 +403,16 @@ namespace PepperDash.Essentials.Core.Bridges
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
}
case "eiscapiadvancedserver":
{
var eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
}
case "eiscapiadvancedclient":
{
var eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
}
case "vceiscapiadv":
case "vceiscapiadvanced":
{

View File

@@ -875,6 +875,48 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("ParticipantAudioMuteToggleStart")]
public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 501,
JoinSpan = 50
},
new JoinMetadata
{
Description = "Toggles the participant's audio mute status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ParticipantVideoMuteToggleStart")]
public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 801,
JoinSpan = 50
},
new JoinMetadata
{
Description = "Toggles the participant's video mute status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ParticipantPinToggleStart")]
public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 1101,
JoinSpan = 50
},
new JoinMetadata
{
Description = "Toggles the participant's pin status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
#endregion
@@ -1195,7 +1237,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
Description = "advance selfview position",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
});
[JoinName("DirectoryEntrySelectedName")]
public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete(
@@ -2132,6 +2174,47 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
JoinType = eJoinType.Digital
});
[JoinName("ParticipantAudioMuteToggleStart")]
public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 500,
JoinSpan = 50
},
new JoinMetadata
{
Description = "Toggles the participant's audio mute status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ParticipantVideoMuteToggleStart")]
public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 800,
JoinSpan = 50
},
new JoinMetadata
{
Description = "Toggles the participant's video mute status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ParticipantPinToggleStart")]
public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 1100,
JoinSpan = 50
},
new JoinMetadata
{
Description = "Toggles the participant's pin status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
#endregion

View File

@@ -1,162 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Responsible for updating config at runtime, and writing the updates out to a local file
/// </summary>
public class ConfigWriter
{
public const string LocalConfigFolder = "LocalConfig";
public const long WriteTimeout = 30000;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Responsible for updating config at runtime, and writing the updates out to a local file
/// </summary>
public class ConfigWriter
{
public const string LocalConfigFolder = "LocalConfig";
public const long WriteTimeout = 30000;
public static CTimer WriteTimer;
static CCriticalSection fileLock = new CCriticalSection();
/// <summary>
/// Updates the config properties of a device
/// </summary>
/// <param name="deviceKey"></param>
/// <param name="properties"></param>
/// <returns></returns>
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
{
bool success = false;
// Get the current device config
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
if (deviceConfig != null)
{
// Replace the current properties JToken with the new one passed into this method
deviceConfig.Properties = properties;
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateDeviceConfig(DeviceConfig config)
{
bool success = false;
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
if (deviceConfig != null)
{
deviceConfig = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateRoomConfig(DeviceConfig config)
{
bool success = false;
var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
if (deviceConfig != null)
{
deviceConfig = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
/// <summary>
/// Resets (or starts) the write timer
/// </summary>
static void ResetTimer()
{
if (WriteTimer == null)
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
WriteTimer.Reset(WriteTimeout);
Debug.Console(1, "Config File write timer has been reset.");
}
/// <summary>
/// Writes the current config to a file in the LocalConfig subfolder
/// </summary>
/// <returns></returns>
private static void WriteConfigFile(object o)
{
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
WriteFile(filePath, configData);
}
/// <summary>
/// Writes
/// </summary>
/// <param name="filepath"></param>
/// <param name="o"></param>
public static void WriteFile(string filePath, string configData)
{
if (WriteTimer != null)
WriteTimer.Stop();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(configData);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
}
static CCriticalSection fileLock = new CCriticalSection();
/// <summary>
/// Updates the config properties of a device
/// </summary>
/// <param name="deviceKey"></param>
/// <param name="properties"></param>
/// <returns></returns>
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
{
bool success = false;
// Get the current device config
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
if (deviceConfig != null)
{
// Replace the current properties JToken with the new one passed into this method
deviceConfig.Properties = properties;
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateDeviceConfig(DeviceConfig config)
{
bool success = false;
var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key));
if (deviceConfigIndex >= 0)
{
ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateRoomConfig(DeviceConfig config)
{
bool success = false;
var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key));
if (roomConfigIndex >= 0)
{
ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config;
Debug.Console(1, "Updated room of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
/// <summary>
/// Resets (or starts) the write timer
/// </summary>
static void ResetTimer()
{
if (WriteTimer == null)
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
WriteTimer.Reset(WriteTimeout);
Debug.Console(1, "Config File write timer has been reset.");
}
/// <summary>
/// Writes the current config to a file in the LocalConfig subfolder
/// </summary>
/// <returns></returns>
private static void WriteConfigFile(object o)
{
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
WriteFile(filePath, configData);
}
/// <summary>
/// Writes
/// </summary>
/// <param name="filepath"></param>
/// <param name="o"></param>
public static void WriteFile(string filePath, string configData)
{
if (WriteTimer != null)
WriteTimer.Stop();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(configData);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
}
}

View File

@@ -20,8 +20,23 @@ namespace PepperDash.Essentials.Core
/// <param name="json"></param>
public static void DoDeviceActionWithJson(string json)
{
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
DoDeviceAction(action);
if (String.IsNullOrEmpty(json))
{
CrestronConsole.ConsoleCommandResponse(
"Please provide a JSON object matching the format {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}.\r\nIf the method has no parameters, the \"params\" object may be omitted.");
return;
}
try
{
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
DoDeviceAction(action);
}
catch (Exception ex)
{
CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}");
}
}
@@ -33,29 +48,47 @@ namespace PepperDash.Essentials.Core
{
var key = action.DeviceKey;
var obj = FindObjectOnPath(key);
if (obj == null)
return;
if (obj == null)
{
CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key);
return;
}
CType t = obj.GetType();
var method = t.GetMethod(action.MethodName);
if (method == null)
{
Debug.Console(0, "Method '{0}' not found", action.MethodName);
return;
}
var mParams = method.GetParameters();
// Add empty params if not provided
if (action.Params == null) action.Params = new object[0];
if (mParams.Length > action.Params.Length)
{
Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length);
return;
}
object[] convertedParams = mParams
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
object ret = method.Invoke(obj, convertedParams);
if (action.Params == null)
{
//no params, so setting action.Params to empty array
action.Params = new object[0];
}
CType t = obj.GetType();
try
{
var methods = t.GetMethods().Where(m => m.Name == action.MethodName).ToList();
var method = methods.Count == 1 ? methods[0] : methods.FirstOrDefault(m => m.GetParameters().Length == action.Params.Length);
if (method == null)
{
CrestronConsole.ConsoleCommandResponse(
"Unable to find method with name {0} and that matches parameters {1}", action.MethodName,
action.Params);
return;
}
var mParams = method.GetParameters();
var convertedParams = mParams
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
var ret = method.Invoke(obj, convertedParams);
CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name,
action.DeviceKey);
}
catch (Exception ex)
{
CrestronConsole.ConsoleCommandResponse("Unable to call method with name {0}. {1}", action.MethodName,
ex.Message);}
}
/// <summary>

View File

@@ -7,6 +7,8 @@ using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core.Devices
{
@@ -52,6 +54,8 @@ namespace PepperDash.Essentials.Core.Devices
Name = config.Name;
}
/// <summary>
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
/// </summary>

View File

@@ -375,7 +375,7 @@ namespace PepperDash.Essentials
{
try
{
if (typeof (IPluginDeviceFactory).IsAssignableFrom(type))
if (typeof (IPluginDeviceFactory).IsAssignableFrom(type) && !type.IsAbstract)
{
var plugin =
(IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);

View File

@@ -8,6 +8,8 @@ using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common.Codec;
@@ -25,7 +27,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
Focus = 8
}
public abstract class CameraBase : EssentialsDevice, IRoutingOutputs
public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs
{
public eCameraControlMode ControlMode { get; protected set; }
@@ -70,12 +72,18 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
// A bitmasked value to indicate the movement capabilites of this camera
protected eCameraCapabilities Capabilities { get; set; }
protected CameraBase(string key, string name) :
base(key, name)
{
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
protected CameraBase(DeviceConfig config) : base(config)
{
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
ControlMode = eCameraControlMode.Manual;
ControlMode = eCameraControlMode.Manual;
}
protected CameraBase(string key, string name) :
this (new DeviceConfig{Name = name, Key = key})
{
}
protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey,

View File

@@ -122,6 +122,7 @@
<Compile Include="Display\PanasonicThDisplay.cs" />
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
<Compile Include="VideoCodec\Interfaces\IHasSelfviewSize.cs" />
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
<Compile Include="Codec\iHasCallFavorites.cs" />
<Compile Include="Codec\iHasCallHistory.cs" />

View File

@@ -27,8 +27,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [ ] Consider modifying to report button visibility in func
BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [ ] Consider modifying to report button visibility in func
BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func
BoolFeedback CanSwapContentWithThumbnailFeedback { get; }
BoolFeedback ContentSwappedWithThumbnailFeedback { get; }

View File

@@ -90,5 +90,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
public bool HandIsRaisedFb { get; set; }
public bool IsPinnedFb { get; set; }
public int ScreenIndexIsPinnedToFb { get; set; }
public Participant()
{
// Initialize to -1 (no screen)
ScreenIndexIsPinnedToFb = -1;
}
}
}

View File

@@ -0,0 +1,13 @@
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface IHasSelfviewSize
{
StringFeedback SelfviewPipSizeFeedback { get; }
void SelfviewPipSizeSet(CodecCommandWithLabel size);
void SelfviewPipSizeToggle();
}
}

View File

@@ -28,6 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
{
private const int XSigEncoding = 28591;
protected const int MaxParticipants = 50;
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
protected VideoCodecBase(DeviceConfig config)
: base(config)
@@ -529,33 +530,89 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{
// make sure to update the values when the EISC comes online
trilist.OnlineStatusChange += (sender, args) =>
{
if (sender.IsOnline)
{
UpdateParticipantsXSig(codec, trilist, joinMap);
}
};
// set actions and update the values when the list changes
codec.Participants.ParticipantsListHasChanged += (sender, args) =>
{
string participantsXSig;
SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants);
if (codec.Participants.CurrentParticipants.Count == 0)
{
participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
return;
}
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
UpdateParticipantsXSig(codec, trilist, joinMap);
};
// TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL
// add method here to decode the xsig info and trigger actions
//trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, DecodeParticipantsXSig);
}
private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{
string participantsXSig;
if (codec.Participants.CurrentParticipants.Count == 0)
{
participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
return;
}
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
}
/// <summary>
/// Sets the actions for each participant in the list
/// </summary>
private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List<Participant> currentParticipants)
{
uint index = 0; // track the index of the participant in the
foreach (var participant in currentParticipants)
{
var p = participant;
if (index > MaxParticipants) break;
var audioMuteCodec = this as IHasParticipantAudioMute;
if (audioMuteCodec != null)
{
trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index,
() => audioMuteCodec.ToggleAudioForParticipant(p.UserId));
trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index,
() => audioMuteCodec.ToggleVideoForParticipant(p.UserId));
}
var pinCodec = this as IHasParticipantPinUnpin;
if (pinCodec != null)
{
trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index,
() => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo));
}
index++;
}
// Clear out any previously set actions
while (index < MaxParticipants)
{
trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index);
trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index);
trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index);
index++;
}
}
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
{
const int maxParticipants = 50;
const int maxParticipants = MaxParticipants;
const int maxDigitals = 7;
const int maxStrings = 1;
const int maxAnalogs = 1;
@@ -571,14 +628,49 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
if (meetingIndex >= maxParticipants * offset) break;
Debug.Console(2, this,
@"Updating Participant on xsig:
Name: {0} (s{9})
AudioMute: {1} (d{10})
VideoMute: {2} (d{11})
CanMuteVideo: {3} (d{12})
CanUMuteVideo: {4} (d{13})
IsHost: {5} (d{14})
HandIsRaised: {6} (d{15})
IsPinned: {7} (d{16})
ScreenIndexIsPinnedTo: {8} (a{17})
",
participant.Name,
participant.AudioMuteFb,
participant.VideoMuteFb,
participant.CanMuteVideo,
participant.CanUnmuteVideo,
participant.IsHost,
participant.HandIsRaisedFb,
participant.IsPinnedFb,
participant.ScreenIndexIsPinnedToFb,
stringIndex + 1,
digitalIndex + 1,
digitalIndex + 2,
digitalIndex + 3,
digitalIndex + 4,
digitalIndex + 5,
digitalIndex + 6,
digitalIndex + 7,
analogIndex + 1
);
//digitals
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb);
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb);
Debug.Console(2, this, "Index: {0} byte value: {1}", digitalIndex + 7, ComTextHelper.GetEscapedText(tokenArray[digitalIndex + 6].GetBytes()));
//serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
@@ -615,48 +707,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
analogIndex += maxAnalogs;
}
return GetXSigString(tokenArray);
}
var returnString = GetXSigString(tokenArray);
// TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL
private void DecodeParticipantsXSig(string xsigData)
{
if (string.IsNullOrEmpty(xsigData)) return;
var bytes = Encoding.GetEncoding(XSigEncoding).GetBytes(xsigData);
using (var xsigStream = new XSigTokenStreamReader(new MemoryStream(bytes)))
{
XSigToken token = null;
while ((token = xsigStream.ReadXSigToken()) != null)
{
switch (token.TokenType)
{
case XSigTokenType.Digital:
{
var data = token as XSigDigitalToken;
if (data == null) return;
Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}",
data.TokenType, data.Index, data.Value.ToString());
break;
}
case XSigTokenType.Analog:
{
var data = token as XSigAnalogToken;
if (data == null) return;
Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}",
data.TokenType, data.Index, data.Value);
break;
}
case XSigTokenType.Serial:
{
var data = token as XSigSerialToken;
if (data == null) return;
Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", data.TokenType, data.Index,
data.Value);
break;
}
}
}
}
//Debug.Console(2, this, "{0}", ComTextHelper.GetEscapedText(Encoding.GetEncoding(28591).GetBytes(returnString)));
return returnString;
}
private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
@@ -672,7 +728,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
}
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
private List<Meeting> _currentMeetings = new List<Meeting>();
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
@@ -684,7 +739,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
codec.CodecSchedule.MeetingWarningMinutes = i;
});
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () =>
{
var mtg = 1;
@@ -694,7 +748,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (_currentMeetings[index] != null)
Dial(_currentMeetings[index]);
});
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () =>
{
var mtg = 2;
@@ -704,7 +758,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (_currentMeetings[index] != null)
Dial(_currentMeetings[index]);
});
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () =>
{
var mtg = 3;
@@ -729,14 +783,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
var currentTime = DateTime.Now;
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
// - changed var currentMeetings >> field _currentMeetings
//_currentMeetings.Clear();
_currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList();
// TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues
// - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi
var meetingsData = UpdateMeetingsListXSig(_currentMeetings);
trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData);
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count);

View File

@@ -6,8 +6,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
public class ZoomRoomJoinMap : VideoCodecControllerJoinMap
{
// TODO: #697 [X] Set join numbers
#region Digital
[JoinName("CanSwapContentWithThumbnail")]
@@ -119,7 +117,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
Description = "FB Indicates if layout 'Gallery' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutSpeakerIsAvailable")]
@@ -133,7 +131,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
Description = "FB Indicates if layout 'Speaker' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutStripIsAvailable")]
@@ -147,7 +145,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
Description = "FB Indicates if layout 'Strip' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
JoinType = eJoinType.DigitalSerial
});
[JoinName("LayoutShareAllIsAvailable")]
@@ -161,50 +159,65 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
Description = "FB Indicates if layout 'ShareAll' is available",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
JoinType = eJoinType.DigitalSerial
});
[JoinName("ParticipantAudioMuteToggleStart")]
public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
// TODO: #714 [ ] JoinMap >> SelfivewPipSizeToggle
[JoinName("SelfviewPipSizeToggle")]
public JoinDataComplete SelfviewPipSizeToggle = new JoinDataComplete(
new JoinData
{
JoinNumber = 500,
JoinSpan = 100
JoinNumber = 231,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Toggles the participant's audio mute status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
Description = "Toggles the selfview pip size, (aka layout size)",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
});
[JoinName("ParticipantVideoMuteToggleStart")]
public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 800,
JoinSpan = 100
},
new JoinMetadata
{
Description = "Toggles the participant's video mute status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
//[JoinName("ParticipantAudioMuteToggleStart")]
//public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 500,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's audio mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
[JoinName("ParticipantPinToggleStart")]
public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
new JoinData
{
JoinNumber = 1100,
JoinSpan = 100
},
new JoinMetadata
{
Description = "Toggles the participant's pin status",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
//[JoinName("ParticipantVideoMuteToggleStart")]
//public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 800,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's video mute status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
//[JoinName("ParticipantPinToggleStart")]
//public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
// new JoinData
// {
// JoinNumber = 1100,
// JoinSpan = 100
// },
// new JoinMetadata
// {
// Description = "Toggles the participant's pin status",
// JoinCapabilities = eJoinCapabilities.ToSIMPL,
// JoinType = eJoinType.Digital
// });
#endregion
@@ -256,7 +269,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
});
// TODO: #714 [ ] JoinMap >> GetSetSelfviewPipSize
[JoinName("GetSetSelfviewPipSize")]
public JoinDataComplete GetSetSelfviewPipSize = new JoinDataComplete(
new JoinData
{
JoinNumber = 230,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sets and reports the selfview pip size, (aka layout size).",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.DigitalSerial
});
#endregion

View File

@@ -1,3 +1,3 @@
<packages>
<package id="PepperDashCore" version="1.0.45" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
<package id="PepperDashCore" version="1.0.47" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
</packages>