From 114d3af162dafa3afd51f055c69c27c76b1f63ea Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 30 Sep 2020 14:01:59 -0600 Subject: [PATCH 1/9] Adds new classes as examples of the three primary types of device (logic, crestron and third party) --- .../EssentialsPluginTemplateCrestronDevice.cs | 99 ++++++++ .../EssentialsPluginTemplateDevice.cs | 187 +++++++++------ .../EssentialsPluginTemplateFactory.cs | 223 +++++++++++++++--- .../EssentialsPluginTemplateLogicDevice.cs | 86 +++++++ .../PDT.EssentialsPluginTemplate.EPI.csproj | 6 + 5 files changed, 486 insertions(+), 115 deletions(-) create mode 100644 PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateCrestronDevice.cs create mode 100644 PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateLogicDevice.cs diff --git a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateCrestronDevice.cs b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateCrestronDevice.cs new file mode 100644 index 0000000..2377387 --- /dev/null +++ b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateCrestronDevice.cs @@ -0,0 +1,99 @@ +// For Basic SIMPL# Classes +// For Basic SIMPL#Pro classes + +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace EssentialsPluginTemplate +{ + /// + /// Plugin device + /// + /// + /// Rename the class to match the device plugin being developed. + /// + /// + /// "EssentialsPluginDeviceTemplate" renamed to "SamsungMdcDevice" + /// + public class EssentialsPluginTemplateCrestronDevice : CrestronGenericBridgeableBaseDevice + { + /// + /// It is often desirable to store the config + /// + private EssentialsPluginConfigObjectTemplate _config; + + + #region Constructor for Devices without IBasicCommunication. Remove if not needed + /// + /// Plugin device constructor for Crestron devices + /// + /// + /// + /// + /// + public EssentialsPluginTemplateCrestronDevice(string key, string name, EssentialsPluginConfigObjectTemplate config, GenericBase hardware) + : base(key, name, hardware) + { + Debug.Console(0, this, "Constructing new {0} instance", name); + + // The base class takes care of registering the hardware device for you + + // TODO [ ] Update the constructor as needed for the plugin device being developed + + _config = config; + } + + #endregion + + + #region Overrides of EssentialsBridgeableDevice + + /// + /// Links the plugin device to the EISC bridge + /// + /// + /// + /// + /// + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new EssentialsPluginBridgeJoinMapTemplate(joinStart); + + // This adds the join map to the collection on the bridge + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name); + + // TODO [ ] Implement bridge links as needed + + // links to bridge + trilist.SetString(joinMap.DeviceName.JoinNumber, Name); + + trilist.OnlineStatusChange += (o, a) => + { + if (!a.DeviceOnLine) return; + + trilist.SetString(joinMap.DeviceName.JoinNumber, Name); + }; + } + + + #endregion + + } +} + diff --git a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs index 649c7e6..837eb2c 100644 --- a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs +++ b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs @@ -9,7 +9,7 @@ using PepperDash.Essentials.Core.Bridges; namespace EssentialsPluginTemplate { /// - /// Plugin device + /// Plugin device template for third party devices that use IBasicCommunication /// /// /// Rename the class to match the device plugin being developed. @@ -17,15 +17,26 @@ namespace EssentialsPluginTemplate /// /// "EssentialsPluginDeviceTemplate" renamed to "SamsungMdcDevice" /// - public class EssentialsPluginDeviceTemplate : EssentialsBridgeableDevice - { - // TODO [ ] Add, modify, remove properties and fields as needed for the plugin being developed + public class EssentialsPluginTemplateDevice : EssentialsBridgeableDevice + { + /// + /// It is often desirable to store the config + /// + private EssentialsPluginConfigObjectTemplate _config; + + #region IBasicCommunication Properties and Constructor. Remove if not needed. + + // TODO [ ] Add, modify, remove properties and fields as needed for the plugin being developed private readonly IBasicCommunication _comms; private readonly GenericCommunicationMonitor _commsMonitor; // _comms gather for ASCII based API's // TODO [ ] If not using an ASCII based API, delete the properties below private readonly CommunicationGather _commsGather; + + /// + /// Set this value to that of the delimiter used by the API (if applicable) + /// private const string CommsDelimiter = "\r"; // _comms byte buffer for HEX/byte based API's @@ -33,7 +44,6 @@ namespace EssentialsPluginTemplate private byte[] _commsByteBuffer = { }; - private EssentialsPluginConfigObjectTemplate _config; /// /// Connects/disconnects the comms of the plugin device @@ -75,13 +85,13 @@ namespace EssentialsPluginTemplate public IntFeedback StatusFeedback { get; private set; } /// - /// Plugin device constructor + /// Plugin device constructor for devices that need IBasicCommunication /// /// /// /// /// - public EssentialsPluginDeviceTemplate(string key, string name, EssentialsPluginConfigObjectTemplate config, IBasicCommunication comms) + public EssentialsPluginTemplateDevice(string key, string name, EssentialsPluginConfigObjectTemplate config, IBasicCommunication comms) : base(key, name) { Debug.Console(0, this, "Constructing new {0} instance", name); @@ -103,79 +113,28 @@ namespace EssentialsPluginTemplate // device comms is IP **ELSE** device comms is RS232 socket.ConnectionChange += socket_ConnectionChange; Connect = true; - } + } - // _comms gather for ASCII based API's - // TODO [ ] If not using an ASCII based API, delete the properties below + #region Communication data event handlers. Comment out any that don't apply to the API type + + // Only one of the below handlers should be necessary. + + // _comms gather for any API that has a defined delimiter + // TODO [ ] If not using an ASCII based API, remove the line below _commsGather = new CommunicationGather(_comms, CommsDelimiter); - AddPostActivationAction(() => _commsGather.LineReceived += Handle_LineRecieved); + _commsGather.LineReceived += Handle_LineRecieved; - // _comms byte buffer for HEX/byte based API's - // TODO [ ] If not using an HEX/byte based API, delete the properties below + // _comms byte buffer for HEX/byte based API's with no delimiter + // TODO [ ] If not using an HEX/byte based API, remove the line below _comms.BytesReceived += Handle_BytesReceived; - AddPostActivationAction(() => _comms.BytesReceived += Handle_BytesReceived); - } - #region Overrides of EssentialsBridgeableDevice + // _comms byte buffer for HEX/byte based API's with no delimiter + // TODO [ ] If not using an HEX/byte based API, remove the line below + _comms.TextReceived += Handle_TextReceived; - /// - /// Links the plugin device to the EISC bridge - /// - /// - /// - /// - /// - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new EssentialsPluginBridgeJoinMapTemplate(joinStart); + #endregion + } - // This adds the join map to the collection on the bridge - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - - var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); - - if (customJoins != null) - { - joinMap.SetCustomJoinData(customJoins); - } - - Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name); - - // TODO [ ] Implement bridge links as needed - - // links to bridge - trilist.SetString(joinMap.DeviceName.JoinNumber, Name); - - trilist.SetBoolSigAction(joinMap.Connect.JoinNumber, sig => Connect = sig); - ConnectFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Connect.JoinNumber]); - - StatusFeedback.LinkInputSig(trilist.UShortInput[joinMap.Status.JoinNumber]); - OnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - - UpdateFeedbacks(); - - trilist.OnlineStatusChange += (o, a) => - { - if (!a.DeviceOnLine) return; - - trilist.SetString(joinMap.DeviceName.JoinNumber, Name); - UpdateFeedbacks(); - }; - } - - private void UpdateFeedbacks() - { - // TODO [ ] Update as needed for the plugin being developed - ConnectFeedback.FireUpdate(); - OnlineFeedback.FireUpdate(); - StatusFeedback.FireUpdate(); - } - - #endregion private void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs args) { @@ -186,20 +145,28 @@ namespace EssentialsPluginTemplate StatusFeedback.FireUpdate(); } - // TODO [ ] If not using an ASCII based API, delete the properties below + // TODO [ ] If not using an API with a delimeter, delete the method below private void Handle_LineRecieved(object sender, GenericCommMethodReceiveTextArgs args) { // TODO [ ] Implement method throw new System.NotImplementedException(); } - // TODO [ ] If not using an HEX/byte based API, delete the properties below + // TODO [ ] If not using an HEX/byte based API with no delimeter, delete the method below private void Handle_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args) { // TODO [ ] Implement method throw new System.NotImplementedException(); } + // TODO [ ] If not using an ASCII based API with no delimeter, delete the method below + void Handle_TextReceived(object sender, GenericCommMethodReceiveTextArgs e) + { + // TODO [ ] Implement method + throw new System.NotImplementedException(); + } + + // TODO [ ] If not using an ACII based API, delete the properties below /// /// Sends text to the device plugin comms @@ -239,8 +206,74 @@ namespace EssentialsPluginTemplate public void Poll() { // TODO [ ] Update Poll method as needed for the plugin being developed + // Example: SendText("getstatus"); throw new System.NotImplementedException(); - } - } + } + + #endregion + + + #region Overrides of EssentialsBridgeableDevice + + /// + /// Links the plugin device to the EISC bridge + /// + /// + /// + /// + /// + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new EssentialsPluginBridgeJoinMapTemplate(joinStart); + + // This adds the join map to the collection on the bridge + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name); + + // TODO [ ] Implement bridge links as needed + + // links to bridge + trilist.SetString(joinMap.DeviceName.JoinNumber, Name); + + trilist.SetBoolSigAction(joinMap.Connect.JoinNumber, sig => Connect = sig); + ConnectFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Connect.JoinNumber]); + + StatusFeedback.LinkInputSig(trilist.UShortInput[joinMap.Status.JoinNumber]); + OnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + + UpdateFeedbacks(); + + trilist.OnlineStatusChange += (o, a) => + { + if (!a.DeviceOnLine) return; + + trilist.SetString(joinMap.DeviceName.JoinNumber, Name); + UpdateFeedbacks(); + }; + } + + private void UpdateFeedbacks() + { + // TODO [ ] Update as needed for the plugin being developed + ConnectFeedback.FireUpdate(); + OnlineFeedback.FireUpdate(); + StatusFeedback.FireUpdate(); + } + + #endregion + + } } diff --git a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs index 76e5baa..8cfa212 100644 --- a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs +++ b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs @@ -1,19 +1,20 @@ using System.Collections.Generic; using PepperDash.Core; using PepperDash.Essentials.Core; +using Crestron.SimplSharpPro.UI; namespace EssentialsPluginTemplate { /// - /// Plugin device factory + /// Plugin device factory for devices that use IBasicCommunication /// /// /// Rename the class to match the device plugin being developed /// /// - /// "EssentialsPluginFactoryTemplate" renamed to "SamsungMdcFactory" + /// "EssentialsPluginFactoryTemplate" renamed to "MyDeviceFactory" /// - public class EssentialsPluginFactoryTemplate : EssentialsPluginDeviceFactory + public class EssentialsPluginFactoryTemplate : EssentialsPluginDeviceFactory { /// /// Plugin device factory constructor @@ -22,14 +23,14 @@ namespace EssentialsPluginTemplate /// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin /// /// + /// Set the minimum Essentials Framework Version /// - /// // Set the minimum Essentials Framework Version - /// MinimumEssentialsFrameworkVersion = "1.5.5"; - /// // In the constructor we initialize the list with the typenames that will build an instance of this device -#pragma warning disable 1570 + /// MinimumEssentialsFrameworkVersion = "1.6.4; + /// + /// In the constructor we initialize the list with the typenames that will build an instance of this device + /// /// TypeNames = new List() { "SamsungMdc", "SamsungMdcDisplay" }; -#pragma warning restore 1570 - /// + /// /// public EssentialsPluginFactoryTemplate() { @@ -54,39 +55,185 @@ namespace EssentialsPluginTemplate /// public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) { - Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type); + Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type); - // get the plugin device properties configuration object & check for null + // get the plugin device properties configuration object & check for null var propertiesConfig = dc.Properties.ToObject(); - if (propertiesConfig == null) - { - Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name); - return null; - } + if (propertiesConfig == null) + { + Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name); + return null; + } - // TODO [ ] Discuss with Andrew/Neil on recommended best practice - - // Method 1 - //var username = dc.Properties["control"].Value("tcpSshProperties").Username; - //var password = dc.Properties["control"].Value("tcpSshProperties").Password; - //var method = dc.Properties["control"].Value("method"); - - // Method 2 - Returns a JValue, has to be casted to string - var username = (string)dc.Properties["control"]["tcpSshProperties"]["username"]; - var password = (string)dc.Properties["control"]["tcpSshProperties"]["password"]; - var method = (string)dc.Properties["control"]["method"]; - - // build the plugin device comms & check for null - // TODO { ] As of PepperDash Core 1.0.41, HTTP and HTTPS are not valid eControlMethods and will throw an exception. - var comms = CommFactory.CreateCommForDevice(dc); - if (comms == null) - { - Debug.Console(0, "[{0}] Factory: failed to create comm for {1}", dc.Key, dc.Name); - return null; - } + // attempt build the plugin device comms device & check for null + // TODO { ] As of PepperDash Core 1.0.41, HTTP and HTTPS are not valid eControlMethods and will throw an exception. + var comms = CommFactory.CreateCommForDevice(dc); + if (comms == null) + { + Debug.Console(1, "[{0}] Factory Notice: No control object present for device {1}", dc.Key, dc.Name); + return null; + } + else + { + return new EssentialsPluginTemplateDevice(dc.Key, dc.Name, propertiesConfig, comms); + } - return new EssentialsPluginDeviceTemplate(dc.Key, dc.Name, propertiesConfig, comms); } } -} \ No newline at end of file + + /// + /// Plugin device factory for logic devices that don't communicate + /// + /// + /// Rename the class to match the device plugin being developed + /// + /// + /// "EssentialsPluginFactoryTemplate" renamed to "MyLogicDeviceFactory" + /// + public class EssentialsPluginFactoryLogicDeviceTemplate : EssentialsPluginDeviceFactory + { + /// + /// Plugin device factory constructor + /// + /// + /// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin + /// + /// + /// Set the minimum Essentials Framework Version + /// + /// MinimumEssentialsFrameworkVersion = "1.6.4; + /// + /// In the constructor we initialize the list with the typenames that will build an instance of this device + /// + /// TypeNames = new List() { "SamsungMdc", "SamsungMdcDisplay" }; + /// + /// + public EssentialsPluginFactoryLogicDeviceTemplate() + { + // Set the minimum Essentials Framework Version + // TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against + MinimumEssentialsFrameworkVersion = "1.6.4"; + + // In the constructor we initialize the list with the typenames that will build an instance of this device + // TODO [ ] Update the TypeNames for the plugin being developed + TypeNames = new List() { "examplePluginLogicDevice" }; + } + + /// + /// Builds and returns an instance of EssentialsPluginTemplateLogicDevice + /// + /// device configuration + /// plugin device or null + /// + /// The example provided below takes the device key, name, properties config and the comms device created. + /// Modify the EssetnialsPlugingDeviceTemplate constructor as needed to meet the requirements of the plugin device. + /// + /// + public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) + { + + Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type); + + // get the plugin device properties configuration object & check for null + var propertiesConfig = dc.Properties.ToObject(); + if (propertiesConfig == null) + { + Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name); + return null; + } + + var controlConfig = CommFactory.GetControlPropertiesConfig(dc); + + if (controlConfig == null) + { + return new EssentialsPluginTemplateLogicDevice(dc.Key, dc.Name, propertiesConfig); + } + else + { + Debug.Console(0, "[{0}] Factory: Unable to get control properties from device config for {1}", dc.Key, dc.Name); + return null; + } + } + } + + /// + /// Plugin device factory for Crestron wrapper devices + /// + /// + /// Rename the class to match the device plugin being developed + /// + /// + /// "EssentialsPluginFactoryTemplate" renamed to "MyCrestronDeviceFactory" + /// + public class EssentialsPluginFactoryCrestronDeviceTemplate : EssentialsPluginDeviceFactory + { + /// + /// Plugin device factory constructor + /// + /// + /// Update the MinimumEssentialsFrameworkVersion & TypeNames as needed when creating a plugin + /// + /// + /// Set the minimum Essentials Framework Version + /// + /// MinimumEssentialsFrameworkVersion = "1.6.4; + /// + /// In the constructor we initialize the list with the typenames that will build an instance of this device + /// + /// TypeNames = new List() { "SamsungMdc", "SamsungMdcDisplay" }; + /// + /// + public EssentialsPluginFactoryCrestronDeviceTemplate() + { + // Set the minimum Essentials Framework Version + // TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against + MinimumEssentialsFrameworkVersion = "1.6.4"; + + // In the constructor we initialize the list with the typenames that will build an instance of this device + // TODO [ ] Update the TypeNames for the plugin being developed + TypeNames = new List() { "examplePluginCrestronDevice" }; + } + + /// + /// Builds and returns an instance of EssentialsPluginTemplateCrestronDevice + /// + /// device configuration + /// plugin device or null + /// + /// The example provided below takes the device key, name, properties config and the comms device created. + /// Modify the EssetnialsPlugingDeviceTemplate constructor as needed to meet the requirements of the plugin device. + /// + /// + public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) + { + + Debug.Console(1, "[{0}] Factory Attempting to create new device from type: {1}", dc.Key, dc.Type); + + // get the plugin device properties configuration object & check for null + var propertiesConfig = dc.Properties.ToObject(); + if (propertiesConfig == null) + { + Debug.Console(0, "[{0}] Factory: failed to read properties config for {1}", dc.Key, dc.Name); + return null; + } + + var controlConfig = CommFactory.GetControlPropertiesConfig(dc); + + if (controlConfig == null) + { + var myTouchpanel = new Tsw760(controlConfig.IpIdInt, Global.ControlSystem); + + return new EssentialsPluginTemplateCrestronDevice(dc.Key, dc.Name, propertiesConfig, myTouchpanel); + } + else + { + Debug.Console(0, "[{0}] Factory: Unable to get control properties from device config for {1}", dc.Key, dc.Name); + return null; + } + } + } + +} + + \ No newline at end of file diff --git a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateLogicDevice.cs b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateLogicDevice.cs new file mode 100644 index 0000000..eda5ad0 --- /dev/null +++ b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateLogicDevice.cs @@ -0,0 +1,86 @@ +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace EssentialsPluginTemplate +{ + /// + /// Plugin device template for logic devices that don't communicate outside the program + /// + /// + /// Rename the class to match the device plugin being developed. + /// + /// + /// "EssentialsPluginTemplateLogicDevice" renamed to "SamsungMdcDevice" + /// + public class EssentialsPluginTemplateLogicDevice : EssentialsBridgeableDevice + { + /// + /// It is often desirable to store the config + /// + private EssentialsPluginConfigObjectTemplate _config; + + /// + /// Plugin device constructor + /// + /// + /// + /// + public EssentialsPluginTemplateLogicDevice(string key, string name, EssentialsPluginConfigObjectTemplate config) + : base(key, name) + { + Debug.Console(0, this, "Constructing new {0} instance", name); + + // TODO [ ] Update the constructor as needed for the plugin device being developed + + _config = config; + } + + #region Overrides of EssentialsBridgeableDevice + + /// + /// Links the plugin device to the EISC bridge + /// + /// + /// + /// + /// + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new EssentialsPluginBridgeJoinMapTemplate(joinStart); + + // This adds the join map to the collection on the bridge + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name); + + // TODO [ ] Implement bridge links as needed + + // links to bridge + trilist.SetString(joinMap.DeviceName.JoinNumber, Name); + + trilist.OnlineStatusChange += (o, a) => + { + if (!a.DeviceOnLine) return; + + trilist.SetString(joinMap.DeviceName.JoinNumber, Name); + }; + } + + #endregion + + } +} + diff --git a/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.EPI.csproj b/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.EPI.csproj index 6517361..6dd00f2 100644 --- a/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.EPI.csproj +++ b/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.EPI.csproj @@ -46,6 +46,10 @@ off + + False + ..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll + False ..\packages\PepperDashEssentials\lib\net35\Essentials Devices Common.dll @@ -95,6 +99,8 @@ + + From 26d049736225e7f038fefcad3ac5d79f295497c2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 30 Sep 2020 14:18:43 -0600 Subject: [PATCH 2/9] Updates readme documentation --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 9447de4..67a4614 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,15 @@ Provided under MIT license Fork this repo when creating a new plugin for Essentials. For more information about plugins, refer to the Essentials Wiki [Plugins](https://github.com/PepperDash/Essentials/wiki/Plugins) article. +This repo contains example classes for the three main categories of devices: +* `EssentialsPluginTemplateDevice`: Used for most third party devices which require communication over a streaming mechanism such as a Com port, TCP/SSh/UDP socket, CEC, etc +* `EssentialsPluginTemplateLogicDevice`: Used for devices that contain logic, but don't require any communication with third parties outside the program +* `EssentialsPluginTemplateCrestronDevice`: Used for devices that represent a piece of Crestron hardware + +There are matching factory classes for each of the three categories of devices. The `EssentialsPluginTemplateConfigObject` should be used as a template and modified for any of the categories of device. Same goes for the `EssentialsPluginTemplateBridgeJoinMap`. + +This also illustrates how a plugin can contain multiple devices. + ## Cloning Instructions After forking this repository into your own GitHub space, you can create a new repository using this one as the template. Then you must install the necessary dependencies as indicated below. From 4143783d2e8b8b58f47f3307629fbf2a879a5dfb Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 5 Feb 2021 10:57:39 -0700 Subject: [PATCH 3/9] Adds example of GenericQueue on EssentialsPluginTemplateDevice and updates dependency version to 1.7.5 --- .../EssentialsPluginTemplateDevice.cs | 22 ++++++++++++++++++- .../EssentialsPluginTemplateFactory.cs | 2 +- packages.config | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs index 837eb2c..20c99da 100644 --- a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs +++ b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateDevice.cs @@ -5,6 +5,8 @@ using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; +using PepperDash_Essentials_Core.Queues; + namespace EssentialsPluginTemplate { @@ -24,6 +26,11 @@ namespace EssentialsPluginTemplate /// private EssentialsPluginConfigObjectTemplate _config; + /// + /// Provides a queue and dedicated worker thread for processing feedback messages from a device. + /// + private GenericQueue ReceiveQueue; + #region IBasicCommunication Properties and Constructor. Remove if not needed. // TODO [ ] Add, modify, remove properties and fields as needed for the plugin being developed @@ -100,6 +107,8 @@ namespace EssentialsPluginTemplate _config = config; + ReceiveQueue = new GenericQueue(key + "-rxqueue"); // If you need to set the thread priority, use one of the available overloaded constructors. + ConnectFeedback = new BoolFeedback(() => Connect); OnlineFeedback = new BoolFeedback(() => _commsMonitor.IsOnline); StatusFeedback = new IntFeedback(() => (int)_commsMonitor.Status); @@ -149,7 +158,9 @@ namespace EssentialsPluginTemplate private void Handle_LineRecieved(object sender, GenericCommMethodReceiveTextArgs args) { // TODO [ ] Implement method - throw new System.NotImplementedException(); + + // Enqueues the message to be processed in a dedicated thread, but the specified method + ReceiveQueue.Enqueue(new ProcessStringMessage(args.Text, ProcessFeedbackMessage)); } // TODO [ ] If not using an HEX/byte based API with no delimeter, delete the method below @@ -166,6 +177,15 @@ namespace EssentialsPluginTemplate throw new System.NotImplementedException(); } + /// + /// This method should perform any necessary parsing of feedback messages from the device + /// + /// + void ProcessFeedbackMessage(string message) + { + + } + // TODO [ ] If not using an ACII based API, delete the properties below /// diff --git a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs index 8cfa212..1798d19 100644 --- a/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs +++ b/PDT.EssentialsPluginTemplate.EPI/EssentialsPluginTemplateFactory.cs @@ -188,7 +188,7 @@ namespace EssentialsPluginTemplate { // Set the minimum Essentials Framework Version // TODO [ ] Update the Essentials minimum framework version which this plugin has been tested against - MinimumEssentialsFrameworkVersion = "1.6.4"; + MinimumEssentialsFrameworkVersion = "1.7.5"; // In the constructor we initialize the list with the typenames that will build an instance of this device // TODO [ ] Update the TypeNames for the plugin being developed diff --git a/packages.config b/packages.config index fa05b32..c66e4a9 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From 6fb86d82c8cf2345bd3239e4efa6f9c04e1ffed8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 5 Feb 2021 13:43:28 -0700 Subject: [PATCH 4/9] removes deprecated set-env from build script --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0ccab74..9072303 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -42,7 +42,7 @@ jobs: run: | if("$($Env:GITHUB_REF)".contains("$($Env:RELEASE_BRANCH)")) { Write-Host "Setting build type to Release" - Write-Output "::set-env name=BUILD_TYPE::Release" + Write-Output "echo "BUILD_TYPE='Release'" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append" } # Fetch all tags - name: Fetch tags @@ -52,7 +52,7 @@ jobs: shell: powershell run: | $version = ./.github/scripts/GenerateVersionNumber.ps1 - Write-Output "::set-env name=VERSION::$version" + Write-Output "echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append" # Use the version number to set the version of the assemblies - name: Update AssemblyInfo.cs shell: powershell From 710642bde54b14246d93bd22fc7403313d233b3b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Feb 2021 12:12:14 -0700 Subject: [PATCH 5/9] Update issue templates --- .../ISSUE_TEMPLATE/essentials-plugin-request.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/essentials-plugin-request.md diff --git a/.github/ISSUE_TEMPLATE/essentials-plugin-request.md b/.github/ISSUE_TEMPLATE/essentials-plugin-request.md new file mode 100644 index 0000000..0bee158 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/essentials-plugin-request.md @@ -0,0 +1,17 @@ +--- +name: Essentials Plugin Request +about: Request an Essentials Plugin +title: "[REQUEST] - " +labels: plugin request +assignees: '' + +--- + +** Describe the Plugin ** +What do you want the plugin to do? Is it for a specific device? If it's for a specific device, include the manufacturer and model, along with links to API documentation if available. + +** Does it need to be available in SIMPL Windows? ** +If it does, describe the functionality that should be exposed to SIMPL Windows via EISC. This may include an example join map, or other way of documenting the layout of the EISC. + +** Additional Features or functionality ** +Describe additional features or functionality that this plugin should have. From d46444e424eaa6208fbcbcab4c55a1d9b44625c9 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Wed, 13 Jul 2022 12:10:03 -0500 Subject: [PATCH 6/9] fix: update essentials reference to latest --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index c66e4a9..2a12f4c 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From c323b982aec914af880252c39204403ce0bff962 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Wed, 13 Jul 2022 12:13:15 -0500 Subject: [PATCH 7/9] fix: added nuspec file --- .../PDT.EssentialsPluginTemplate.nuspec | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.nuspec diff --git a/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.nuspec b/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.nuspec new file mode 100644 index 0000000..7b99bed --- /dev/null +++ b/PDT.EssentialsPluginTemplate.EPI/PDT.EssentialsPluginTemplate.nuspec @@ -0,0 +1,21 @@ + + + + PDT.EssentialsPluginTemplate + 2.0.2 + Essentials Plugin Template + PepperDash Technologies + pepperdash + false + MIT + https://github.com/PepperDash/EssentialsPluginTemplate + Copyright 2022 + This software iserves as a template for generating new Essentials-Compliant plugins + crestron 3series 4series samsung + + + + + + + \ No newline at end of file From 2ff646e499301384c4fe2367dbd747e5aa994b1d Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Wed, 13 Jul 2022 12:18:08 -0500 Subject: [PATCH 8/9] fix: updated github workflows --- .github/scripts/GenerateVersionNumber.ps1 | 11 +- .github/scripts/ZipBuildOutput.ps1 | 3 +- .github/workflows/docker.yml | 103 ------- .../essentialsplugins-betabuilds.yml | 271 ++++++++++++++++++ .../essentialsplugins-releasebuilds.yml | 219 ++++++++++++++ 5 files changed, 499 insertions(+), 108 deletions(-) delete mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/essentialsplugins-betabuilds.yml create mode 100644 .github/workflows/essentialsplugins-releasebuilds.yml diff --git a/.github/scripts/GenerateVersionNumber.ps1 b/.github/scripts/GenerateVersionNumber.ps1 index 98bbf3a..5d5a3ec 100644 --- a/.github/scripts/GenerateVersionNumber.ps1 +++ b/.github/scripts/GenerateVersionNumber.ps1 @@ -7,7 +7,8 @@ Foreach ($version in $latestVersions) { $latestVersion = $version Write-Host "Setting latest version to: $latestVersion" } - } catch { + } + catch { Write-Host "Unable to convert $($version). Skipping" continue; } @@ -18,17 +19,19 @@ $phase = "" $newVersionString = "" switch -regex ($Env:GITHUB_REF) { '^refs\/heads\/main*.' { - $newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1) + $newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build } '^refs\/heads\/feature\/*.' { $phase = 'alpha' $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER } '^refs\/heads\/release\/*.' { + $splitRef = $Env:GITHUB_REF -split "/" + $version = [version]($splitRef[-1] -replace "v", "") $phase = 'rc' - $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $version.Major, $version.Minor, $version.Build, $phase, $Env:GITHUB_RUN_NUMBER } - '^refs\/heads\/development*.' { + '^refs\/heads\/dev*.' { $phase = 'beta' $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER } diff --git a/.github/scripts/ZipBuildOutput.ps1 b/.github/scripts/ZipBuildOutput.ps1 index 3f1998b..ca4a9a7 100644 --- a/.github/scripts/ZipBuildOutput.ps1 +++ b/.github/scripts/ZipBuildOutput.ps1 @@ -10,7 +10,7 @@ Get-ChildItem ($destination) $exclusions = @(git submodule foreach --quiet 'echo $name') # Trying to get any .json schema files (not currently working) # Gets any files with the listed extensions. -Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz" | ForEach-Object { +Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.cplz" | ForEach-Object { $allowed = $true; # Exclude any files in submodules foreach ($exclude in $exclusions) { @@ -36,6 +36,7 @@ Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ( Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force } } +Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" } Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force Write-Host "Output Contents post Zip" Get-ChildItem -Path $destination \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index 9072303..0000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: Branch Build Using Docker - -on: - push: - branches: - - feature/* - - hotfix/* - - release/* - - main - - development - -env: - # solution path doesn't need slashes unless there it is multiple folders deep - # solution name does not include extension. .sln is assumed - SOLUTION_PATH: PDT.EssentialsPluginTemplate.EPI - SOLUTION_FILE: PDT.EssentialsPluginTemplate.EPI - # Do not edit this, we're just creating it here - VERSION: 0.0.0-buildtype-buildnumber - # Defaults to debug for build type - BUILD_TYPE: Debug - # Defaults to main as the release branch. Change as necessary - RELEASE_BRANCH: main -jobs: - Build_Project: - runs-on: windows-latest - steps: - # First we checkout the source repo - - name: Checkout repo - uses: actions/checkout@v2 - with: - fetch-depth: 0 - # And any submodules - - name: Checkout submodules - shell: bash - run: | - git config --global url."https://github.com/".insteadOf "git@github.com:" - auth_header="$(git config --local --get http.https://github.com/.extraheader)" - git submodule sync --recursive - git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - # Set the BUILD_TYPE environment variable - - name: Set Build to Release if triggered from main - run: | - if("$($Env:GITHUB_REF)".contains("$($Env:RELEASE_BRANCH)")) { - Write-Host "Setting build type to Release" - Write-Output "echo "BUILD_TYPE='Release'" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append" - } - # Fetch all tags - - name: Fetch tags - run: git fetch --tags - # Generate the appropriate version number - - name: Set Version Number - shell: powershell - run: | - $version = ./.github/scripts/GenerateVersionNumber.ps1 - Write-Output "echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append" - # Use the version number to set the version of the assemblies - - name: Update AssemblyInfo.cs - shell: powershell - run: | - Write-Output ${{ env.VERSION }} - ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }} - - name: restore Nuget Packages - run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion - - name: Login to Docker - uses: azure/docker-login@v1 - with: - username: ${{ secrets.DOCKERHUB_USER }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - # Build the solutions in the docker image - - name: Build Solution - shell: powershell - run: | - Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_PATH)\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" - # Zip up the output files as needed - - name: Zip Build Output - shell: powershell - run: ./.github/scripts/ZipBuildOutput.ps1 - - name: Upload Build Output - uses: actions/upload-artifact@v1 - with: - name: Build - path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip - # Create the release on the source repo - - name: Create Release - id: create_release - uses: actions/create-release@v1 - with: - tag_name: ${{ env.VERSION }} - release_name: ${{ env.VERSION }} - prerelease: ${{contains('debug', env.BUILD_TYPE)}} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Upload the build package to the release - - name: Upload Release Package - id: upload_release - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip - asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip - asset_content_type: application/zip - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/essentialsplugins-betabuilds.yml b/.github/workflows/essentialsplugins-betabuilds.yml new file mode 100644 index 0000000..ad34045 --- /dev/null +++ b/.github/workflows/essentialsplugins-betabuilds.yml @@ -0,0 +1,271 @@ +name: Branch Build Using Docker + +on: + push: + branches: + - feature/* + - hotfix/* + - release/* + - dev* + +env: + # Do not edit this, we're just creating it here + VERSION: 0.0.0-buildtype-buildnumber + # Defaults to debug for build type + BUILD_TYPE: Debug + # Defaults to master as the release branch. Change as necessary + RELEASE_BRANCH: main +jobs: + Build_Project: + runs-on: windows-2019 + steps: + # First we checkout the source repo + - name: Checkout repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + # Fetch all tags + - name: Fetch tags + run: git fetch --tags + # Generate the appropriate version number + - name: Set Version Number + shell: powershell + run: | + $latestVersions = $(git tag --merged origin/main) + $latestVersion = [version]"0.0.0" + Foreach ($version in $latestVersions) { + Write-Host $version + try { + if (([version]$version) -ge $latestVersion) { + $latestVersion = $version + Write-Host "Setting latest version to: $latestVersion" + } + } + catch { + Write-Host "Unable to convert $($version). Skipping" + continue; + } + } + + $newVersion = [version]$latestVersion + $phase = "" + $newVersionString = "" + switch -regex ($Env:GITHUB_REF) { + '^refs\/heads\/main*.' { + $newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build + } + '^refs\/heads\/feature\/*.' { + $phase = 'alpha' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } + '^refs\/heads\/release\/*.' { + $splitRef = $Env:GITHUB_REF -split "/" + $version = [version]($splitRef[-1] -replace "v", "") + $phase = 'rc' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $version.Major, $version.Minor, $version.Build, $phase, $Env:GITHUB_RUN_NUMBER + } + '^refs\/heads\/dev*.' { + $phase = 'beta' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } + '^refs\/heads\/hotfix\/*.' { + $phase = 'hotfix' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } + } + echo "VERSION=$newVersionString" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + # Use the version number to set the version of the assemblies + - name: Update AssemblyInfo.cs + shell: powershell + run: | + function Update-SourceVersion { + Param ([string]$Version) + #$fullVersion = $Version + $baseVersion = [regex]::Match($Version, "(\d+.\d+.\d+).*").captures.groups[1].value + $NewAssemblyVersion = 'AssemblyVersion("' + $baseVersion + '.*")' + Write-Output "AssemblyVersion = $NewAssemblyVersion" + $NewAssemblyInformationalVersion = 'AssemblyInformationalVersion("' + $Version + '")' + Write-Output "AssemblyInformationalVersion = $NewAssemblyInformationalVersion" + foreach ($o in $input) { + Write-output $o.FullName + $TmpFile = $o.FullName + ".tmp" + get-content $o.FullName | + ForEach-Object { + $_ -replace 'AssemblyVersion\(".*"\)', $NewAssemblyVersion } | + ForEach-Object { + $_ -replace 'AssemblyInformationalVersion\(".*"\)', $NewAssemblyInformationalVersion + } > $TmpFile + move-item $TmpFile $o.FullName -force + } + } + function Update-AllAssemblyInfoFiles ( $version ) { + foreach ($file in "AssemblyInfo.cs", "AssemblyInfo.vb" ) { + get-childitem -Path $Env:GITHUB_WORKSPACE -recurse | Where-Object { $_.Name -eq $file } | Update-SourceVersion $version ; + } + } + # validate arguments + $r = [System.Text.RegularExpressions.Regex]::Match($Env:VERSION, "\d+\.\d+\.\d+.*"); + if ($r.Success) { + Write-Output "Updating Assembly Version to $Env:VERSION ..."; + Update-AllAssemblyInfoFiles $Env:VERSION; + } + else { + Write-Output " "; + Write-Output "Error: Input version $Env:VERSION does not match x.y.z format!" + Write-Output " "; + Write-Output "Unable to apply version to AssemblyInfo.cs files"; + } + - name: restore Nuget Packages + run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion + # Set the SOLUTION_PATH + - name: Get SLN Path + shell: powershell + run: | + $solution_path = Get-ChildItem *.sln -recurse + $solution_path = $solution_path.FullName + $solution_path = $solution_path -replace "(?:[^\\]*\\){4}", "" + Write-Output $solution_path + echo "SOLUTION_PATH=$($solution_path)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + # Set the SOLUTION_FILE + - name: Get SLN File + shell: powershell + run: | + $solution_file = Get-ChildItem .\*.sln -recurse -Path "$($Env:GITHUB_WORKSPACE)" + echo "SOLUTION_FILE=$($solution_file.BaseName)"| Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + # Login to Docker + - name: Login to Docker + uses: azure/docker-login@v1 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + # Build the solutions in the docker image + - name: Build Solution + shell: powershell + run: | + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_PATH)"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + # Zip up the output files as needed + - name: Zip Build Output + shell: powershell + run: | + $destination = "$($Env:GITHUB_HOME)\output" + New-Item -ItemType Directory -Force -Path ($destination) + Get-ChildItem ($destination) + $exclusions = "packages" + # Trying to get any .json schema files (not currently working) + # Gets any files with the listed extensions. + Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.nuspec" | ForEach-Object { + $allowed = $true; + # Exclude any files in submodules + foreach ($exclude in $exclusions) { + if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) { + $allowed = $false; + break; + } + } + if ($allowed) { + Write-Host "allowing $($_)" + $_; + } + } | Copy-Item -Destination ($destination) -Force + Write-Host "Getting matching files..." + # Get any files from the output folder that match the following extensions + Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object { + # Replace the extensions with dll and xml and create an array + $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml")) + Write-Host "Filenames:" + Write-Host $filenames + if ($filenames.length -gt 0) { + # Attempt to get the files and return them to the output directory + Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force + } + } + Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" } + Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force + Write-Host "Output Contents post Zip" + Get-ChildItem -Path $destination + # Write the version to a file to be consumed by the push jobs + - name: Write Version + run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt" + # Upload output files + - name: Upload Build Output + uses: actions/upload-artifact@v1 + with: + name: Build + path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + # Upload the Version file as an artifact + - name: Upload version.txt + uses: actions/upload-artifact@v1 + with: + name: Version + path: ${{env.GITHUB_HOME}}\output\version.txt + # Create the release on the source repo + - name: Create Release + id: create_release + uses: fleskesvor/create-release@feature/support-target-commitish + with: + tag_name: ${{ env.VERSION }} + release_name: ${{ env.VERSION }} + prerelease: ${{contains('debug', env.BUILD_TYPE)}} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Upload the build package to the release + - name: Upload Release Package + id: upload_release + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + asset_content_type: application/zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + Push_Nuget_Package: + needs: Build_Project + runs-on: windows-2019 + steps: + - name: Download Build Version Info + uses: actions/download-artifact@v1 + with: + name: Version + - name: Set Version Number + shell: powershell + run: | + Get-ChildItem "./Version" + $version = Get-Content -Path ./Version/version.txt + Write-Host "Version: $version" + echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + Remove-Item -Path ./Version/version.txt + Remove-Item -Path ./Version + - name: Download Build output + uses: actions/download-artifact@v1 + with: + name: Build + path: ./ + - name: Unzip Build file + run: | + Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ + Remove-Item -Path .\*.zip + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse + - name: Get nuget File + shell: powershell + run: | + $nuspec_file = Get-ChildItem *.nuspec -recurse + echo "NUSPEC_FILE=$($nuspec_file.BaseName)"| Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Add nuget.exe + uses: nuget/setup-nuget@v1 + - name: Add Github Packages source + run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }} + # Pushes to nuget, not needed unless publishing publicly + - name: Add nuget.org API Key + run: nuget setApiKey ${{ secrets.NUGET_API_KEY }} + - name: Create nuget package + run: nuget pack "./${{ env.NUSPEC_FILE}}.nuspec" -version ${{ env.VERSION }} + - name: Publish nuget package to Github registry + run: nuget push **/*.nupkg -source github + # Pushes to nuget, not needed unless publishing publicly >> this pushes package to nuget.org + - name: Publish nuget package to nuget.org + run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json diff --git a/.github/workflows/essentialsplugins-releasebuilds.yml b/.github/workflows/essentialsplugins-releasebuilds.yml new file mode 100644 index 0000000..3e169ce --- /dev/null +++ b/.github/workflows/essentialsplugins-releasebuilds.yml @@ -0,0 +1,219 @@ +name: Main Build using Docker + +on: + release: + types: + - released + branches: + - main + +env: + # Do not edit this, we're just creating it here + VERSION: 0.0.0-buildtype-buildnumber + # Defaults to debug for build type + BUILD_TYPE: Debug + # Defaults to master as the release branch. Change as necessary + RELEASE_BRANCH: main +jobs: + Build_Project: + runs-on: windows-2019 + steps: + # First we checkout the source repo + - name: Checkout repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + # Fetch all tags + - name: Fetch tags + run: git fetch --tags + # Generate the appropriate version number + - name: Set Version Number + shell: powershell + env: + TAG_NAME: ${{ github.event.release.tag_name }} + run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + # Use the version number to set the version of the assemblies + - name: Update AssemblyInfo.cs + shell: powershell + run: | + function Update-SourceVersion { + Param ([string]$Version) + #$fullVersion = $Version + $baseVersion = [regex]::Match($Version, "(\d+.\d+.\d+).*").captures.groups[1].value + $NewAssemblyVersion = 'AssemblyVersion("' + $baseVersion + '.*")' + Write-Output "AssemblyVersion = $NewAssemblyVersion" + $NewAssemblyInformationalVersion = 'AssemblyInformationalVersion("' + $Version + '")' + Write-Output "AssemblyInformationalVersion = $NewAssemblyInformationalVersion" + foreach ($o in $input) { + Write-output $o.FullName + $TmpFile = $o.FullName + ".tmp" + get-content $o.FullName | + ForEach-Object { + $_ -replace 'AssemblyVersion\(".*"\)', $NewAssemblyVersion } | + ForEach-Object { + $_ -replace 'AssemblyInformationalVersion\(".*"\)', $NewAssemblyInformationalVersion + } > $TmpFile + move-item $TmpFile $o.FullName -force + } + } + function Update-AllAssemblyInfoFiles ( $version ) { + foreach ($file in "AssemblyInfo.cs", "AssemblyInfo.vb" ) { + get-childitem -Path $Env:GITHUB_WORKSPACE -recurse | Where-Object { $_.Name -eq $file } | Update-SourceVersion $version ; + } + } + # validate arguments + $r = [System.Text.RegularExpressions.Regex]::Match($Env:VERSION, "\d+\.\d+\.\d+.*"); + if ($r.Success) { + Write-Output "Updating Assembly Version to $Env:VERSION ..."; + Update-AllAssemblyInfoFiles $Env:VERSION; + } + else { + Write-Output " "; + Write-Output "Error: Input version $Env:VERSION does not match x.y.z format!" + Write-Output " "; + Write-Output "Unable to apply version to AssemblyInfo.cs files"; + } + - name: restore Nuget Packages + run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion + # Set the SOLUTION_PATH + - name: Get SLN Path + shell: powershell + run: | + $solution_path = Get-ChildItem *.sln -recurse + $solution_path = $solution_path.FullName + $solution_path = $solution_path -replace "(?:[^\\]*\\){4}", "" + Write-Output $solution_path + echo "SOLUTION_PATH=$($solution_path)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + # Set the SOLUTION_FILE + - name: Get SLN File + shell: powershell + run: | + $solution_file = Get-ChildItem .\*.sln -recurse -Path "$($Env:GITHUB_WORKSPACE)" + echo "SOLUTION_FILE=$($solution_file.BaseName)"| Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + # Login to Docker + - name: Login to Docker + uses: azure/docker-login@v1 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + # Build the solutions in the docker image + - name: Build Solution + shell: powershell + run: | + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_PATH)"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + # Zip up the output files as needed + - name: Zip Build Output + shell: powershell + run: | + $destination = "$($Env:GITHUB_HOME)\output" + New-Item -ItemType Directory -Force -Path ($destination) + Get-ChildItem ($destination) + $exclusions = "packages" + # Trying to get any .json schema files (not currently working) + # Gets any files with the listed extensions. + Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.nuspec" | ForEach-Object { + $allowed = $true; + # Exclude any files in submodules + foreach ($exclude in $exclusions) { + if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) { + $allowed = $false; + break; + } + } + if ($allowed) { + Write-Host "allowing $($_)" + $_; + } + } | Copy-Item -Destination ($destination) -Force + Write-Host "Getting matching files..." + # Get any files from the output folder that match the following extensions + Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object { + # Replace the extensions with dll and xml and create an array + $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml")) + Write-Host "Filenames:" + Write-Host $filenames + if ($filenames.length -gt 0) { + # Attempt to get the files and return them to the output directory + Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force + } + } + Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" } + Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force + Write-Host "Output Contents post Zip" + Get-ChildItem -Path $destination + # Write the version to a file to be consumed by the push jobs + - name: Write Version + run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt" + # Upload output files + - name: Upload Build Output + uses: actions/upload-artifact@v1 + with: + name: Build + path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + # Upload the Version file as an artifact + - name: Upload version.txt + uses: actions/upload-artifact@v1 + with: + name: Version + path: ${{env.GITHUB_HOME}}\output\version.txt + # Upload the build package to the release + - name: Upload Release Package + id: upload_release + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + asset_content_type: application/zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + Push_Nuget_Package: + needs: Build_Project + runs-on: windows-2019 + steps: + - name: Download Build Version Info + uses: actions/download-artifact@v1 + with: + name: Version + - name: Set Version Number + shell: powershell + run: | + Get-ChildItem "./Version" + $version = Get-Content -Path ./Version/version.txt + Write-Host "Version: $version" + echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + Remove-Item -Path ./Version/version.txt + Remove-Item -Path ./Version + - name: Download Build output + uses: actions/download-artifact@v1 + with: + name: Build + path: ./ + - name: Unzip Build file + run: | + Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ + Remove-Item -Path .\*.zip + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse + - name: Get nuget File + shell: powershell + run: | + $nuspec_file = Get-ChildItem *.nuspec -recurse + echo "NUSPEC_FILE=$($nuspec_file.BaseName)"| Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Add nuget.exe + uses: nuget/setup-nuget@v1 + - name: Add Github Packages source + run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }} + # Pushes to nuget, not needed unless publishing publicly + - name: Add nuget.org API Key + run: nuget setApiKey ${{ secrets.NUGET_API_KEY }} + - name: Create nuget package + run: nuget pack "./${{ env.NUSPEC_FILE}}.nuspec" -version ${{ env.VERSION }} + - name: Publish nuget package to Github registry + run: nuget push **/*.nupkg -source github + # Pushes to nuget, not needed unless publishing publicly >> this pushes package to nuget.org + - name: Publish nuget package to nuget.org + run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json From fcbf71078105683cc1d02d89623f63721218ed97 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Wed, 13 Jul 2022 12:30:15 -0500 Subject: [PATCH 9/9] fix: updated AssemblyInfo copyright date --- PDT.EssentialsPluginTemplate.EPI/Properties/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PDT.EssentialsPluginTemplate.EPI/Properties/AssemblyInfo.cs b/PDT.EssentialsPluginTemplate.EPI/Properties/AssemblyInfo.cs index b31431b..e8f1480 100644 --- a/PDT.EssentialsPluginTemplate.EPI/Properties/AssemblyInfo.cs +++ b/PDT.EssentialsPluginTemplate.EPI/Properties/AssemblyInfo.cs @@ -3,6 +3,6 @@ [assembly: AssemblyTitle("EssentialsPluginTemplateEpi")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EssentialsPluginTemplateEpi")] -[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyVersion("1.0.0.*")]