Updating HarmonyHub to v0.3.0.
Adding untested Harmony command action.
1.1 --- a/Server/Actions/ActionDisplayMessage.cs Tue Aug 16 12:59:32 2016 +0200
1.2 +++ b/Server/Actions/ActionDisplayMessage.cs Wed Aug 17 13:41:26 2016 +0200
1.3 @@ -1,4 +1,5 @@
1.4 -using SharpLib.Ear;
1.5 +using Ear = SharpLib.Ear;
1.6 +using SharpLib.Ear;
1.7 using System;
1.8 using System.Collections.Generic;
1.9 using System.Drawing;
1.10 @@ -14,7 +15,7 @@
1.11
1.12 [DataContract]
1.13 [AttributeObject(Id = "Display.Message", Name = "Display Message", Description = "Shows a message on your internal display.")]
1.14 - class ActionDisplayMessage : SharpLib.Ear.Action
1.15 + class ActionDisplayMessage : Ear.Action
1.16 {
1.17 [DataMember]
1.18 [AttributeObjectProperty(
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/Server/Actions/ActionHarmonyCommand.cs Wed Aug 17 13:41:26 2016 +0200
2.3 @@ -0,0 +1,76 @@
2.4 +using Ear = SharpLib.Ear;
2.5 +using SharpLib.Ear;
2.6 +using System;
2.7 +using System.Collections.Generic;
2.8 +using System.Linq;
2.9 +using System.Text;
2.10 +using System.Threading.Tasks;
2.11 +using System.Runtime.Serialization;
2.12 +
2.13 +namespace SharpDisplayManager
2.14 +{
2.15 + [DataContract]
2.16 + [AttributeObject(Id = "Harmony.Command", Name = "Harmony Command", Description = "Send a command to your Logitech Harmony Hub.")]
2.17 + class ActionHarmonyCommand : Ear.Action
2.18 + {
2.19 + [DataMember]
2.20 + [AttributeObjectProperty(
2.21 + Id = "Harmony.Command.DeviceId",
2.22 + Name = "Device ID",
2.23 + Description = "The ID of the device this command is associated with."
2.24 + )]
2.25 + public string DeviceId { get; set; } = "";
2.26 +
2.27 +
2.28 + [DataMember]
2.29 + [AttributeObjectProperty(
2.30 + Id = "Harmony.Command.FunctionName",
2.31 + Name = "Function Name",
2.32 + Description = "The name of the function defining this command."
2.33 + )]
2.34 + public string FunctionName { get; set; } = "";
2.35 +
2.36 + /// <summary>
2.37 + ///
2.38 + /// </summary>
2.39 + /// <returns></returns>
2.40 + public override string Brief()
2.41 + {
2.42 + string brief="";
2.43 +
2.44 + if (Program.HarmonyConfig != null)
2.45 + {
2.46 + //What if the device ID is not there anymore?
2.47 + brief += Program.HarmonyConfig.DeviceNameFromId(DeviceId);
2.48 + }
2.49 + else
2.50 + {
2.51 + //No config found just show the device ID then.
2.52 + brief += DeviceId;
2.53 + }
2.54 +
2.55 + brief += " do " + FunctionName;
2.56 +
2.57 + return brief;
2.58 + }
2.59 +
2.60 + /// <summary>
2.61 + ///
2.62 + /// </summary>
2.63 + protected override void DoExecute()
2.64 + {
2.65 + //Fire and forget our command
2.66 + //TODO: check if the harmony client connection is opened
2.67 + if (Program.HarmonyClient!=null)
2.68 + {
2.69 + Program.HarmonyClient.SendCommandAsync(DeviceId, FunctionName);
2.70 + }
2.71 + else
2.72 + {
2.73 + Console.WriteLine("WARNING: No Harmony client connection.");
2.74 + }
2.75 +
2.76 + }
2.77 +
2.78 + }
2.79 +}
3.1 --- a/Server/FormEditObject.cs Tue Aug 16 12:59:32 2016 +0200
3.2 +++ b/Server/FormEditObject.cs Wed Aug 17 13:41:26 2016 +0200
3.3 @@ -35,7 +35,7 @@
3.4 /// <param name="e"></param>
3.5 private void FormEditAction_Load(object sender, EventArgs e)
3.6 {
3.7 - // Populate registered actions
3.8 + // Populate registered object types
3.9 IEnumerable < Type > types = Reflection.GetConcreteClassesDerivedFrom<T>();
3.10 foreach (Type type in types)
3.11 {
3.12 @@ -90,10 +90,10 @@
3.13 /// <summary>
3.14 /// Get properties values from our generated input fields
3.15 /// </summary>
3.16 - private void FetchPropertiesValue(T aAction)
3.17 + private void FetchPropertiesValue(T aObject)
3.18 {
3.19 int ctrlIndex = 0;
3.20 - foreach (PropertyInfo pi in aAction.GetType().GetProperties())
3.21 + foreach (PropertyInfo pi in aObject.GetType().GetProperties())
3.22 {
3.23 AttributeObjectProperty[] attributes =
3.24 ((AttributeObjectProperty[]) pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
3.25 @@ -109,7 +109,7 @@
3.26 continue;
3.27 }
3.28
3.29 - GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aAction); //+1 otherwise we get the label
3.30 + GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aObject); //+1 otherwise we get the label
3.31
3.32 ctrlIndex+=2; //Jump over the label too
3.33 }
3.34 @@ -118,13 +118,13 @@
3.35 /// <summary>
3.36 /// Extend this function to support reading new types of properties.
3.37 /// </summary>
3.38 - /// <param name="aAction"></param>
3.39 - private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aAction)
3.40 + /// <param name="aObject"></param>
3.41 + private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aObject)
3.42 {
3.43 if (aInfo.PropertyType == typeof(int))
3.44 {
3.45 NumericUpDown ctrl=(NumericUpDown)aControl;
3.46 - aInfo.SetValue(aAction,(int)ctrl.Value);
3.47 + aInfo.SetValue(aObject,(int)ctrl.Value);
3.48 }
3.49 else if (aInfo.PropertyType.IsEnum)
3.50 {
3.51 @@ -134,27 +134,30 @@
3.52 enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
3.53 //enumValue = ((ComboBox)aControl).SelectedValue;
3.54 // Set enum value
3.55 - aInfo.SetValue(aAction, enumValue);
3.56 + aInfo.SetValue(aObject, enumValue);
3.57 }
3.58 else if (aInfo.PropertyType == typeof(bool))
3.59 {
3.60 CheckBox ctrl = (CheckBox)aControl;
3.61 - aInfo.SetValue(aAction, ctrl.Checked);
3.62 + aInfo.SetValue(aObject, ctrl.Checked);
3.63 }
3.64 else if (aInfo.PropertyType == typeof(string))
3.65 {
3.66 TextBox ctrl = (TextBox)aControl;
3.67 - aInfo.SetValue(aAction, ctrl.Text);
3.68 + aInfo.SetValue(aObject, ctrl.Text);
3.69 }
3.70 //TODO: add support for other types here
3.71 }
3.72
3.73 +
3.74 /// <summary>
3.75 - ///
3.76 + /// Create a control for the given property.
3.77 /// </summary>
3.78 /// <param name="aInfo"></param>
3.79 - /// <param name="action"></param>
3.80 - private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aAction)
3.81 + /// <param name="aAttribute"></param>
3.82 + /// <param name="aObject"></param>
3.83 + /// <returns></returns>
3.84 + private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aObject)
3.85 {
3.86 if (aInfo.PropertyType == typeof(int))
3.87 {
3.88 @@ -164,7 +167,7 @@
3.89 ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
3.90 ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
3.91 ctrl.Increment = Int32.Parse(aAttribute.Increment);
3.92 - ctrl.Value = (int)aInfo.GetValue(aAction);
3.93 + ctrl.Value = (int)aInfo.GetValue(aObject);
3.94 return ctrl;
3.95 }
3.96 else if (aInfo.PropertyType.IsEnum)
3.97 @@ -194,7 +197,7 @@
3.98
3.99 // Instantiate our enum
3.100 object enumValue = Activator.CreateInstance(aInfo.PropertyType);
3.101 - enumValue = aInfo.GetValue(aAction);
3.102 + enumValue = aInfo.GetValue(aObject);
3.103 //Set the current item
3.104 ctrl.SelectedItem = enumValue.ToString();
3.105
3.106 @@ -205,14 +208,14 @@
3.107 CheckBox ctrl = new CheckBox();
3.108 ctrl.AutoSize = true;
3.109 ctrl.Text = aAttribute.Description;
3.110 - ctrl.Checked = (bool)aInfo.GetValue(aAction);
3.111 + ctrl.Checked = (bool)aInfo.GetValue(aObject);
3.112 return ctrl;
3.113 }
3.114 else if (aInfo.PropertyType == typeof(string))
3.115 {
3.116 TextBox ctrl = new TextBox();
3.117 ctrl.AutoSize = true;
3.118 - ctrl.Text = (string)aInfo.GetValue(aAction);
3.119 + ctrl.Text = (string)aInfo.GetValue(aObject);
3.120 return ctrl;
3.121 }
3.122 //TODO: add support for other control type here
3.123 @@ -253,7 +256,7 @@
3.124 /// Fields must be specified by rows from the left.
3.125 /// </summary>
3.126 /// <param name="aLayout"></param>
3.127 - private void UpdateTableLayoutPanel(T aAction)
3.128 + private void UpdateTableLayoutPanel(T aObject)
3.129 {
3.130 toolTip.RemoveAll();
3.131 //Debug.Print("UpdateTableLayoutPanel")
3.132 @@ -269,17 +272,17 @@
3.133 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
3.134
3.135
3.136 - if (aAction == null)
3.137 + if (aObject == null)
3.138 {
3.139 //Just drop it
3.140 return;
3.141 }
3.142
3.143 - //IEnumerable<PropertyInfo> properties = aAction.GetType().GetProperties().Where(
3.144 + //IEnumerable<PropertyInfo> properties = aObject.GetType().GetProperties().Where(
3.145 // prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
3.146
3.147
3.148 - foreach (PropertyInfo pi in aAction.GetType().GetProperties())
3.149 + foreach (PropertyInfo pi in aObject.GetType().GetProperties())
3.150 {
3.151 AttributeObjectProperty[] attributes = ((AttributeObjectProperty[])pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
3.152 if (attributes.Length != 1)
3.153 @@ -291,7 +294,7 @@
3.154
3.155 //Before anything we need to check if that kind of property is supported by our UI
3.156 //Create the editor
3.157 - Control ctrl = CreateControlForProperty(pi, attribute, aAction);
3.158 + Control ctrl = CreateControlForProperty(pi, attribute, aObject);
3.159 if (ctrl == null)
3.160 {
3.161 //Property type not supported
4.1 --- a/Server/FormMain.cs Tue Aug 16 12:59:32 2016 +0200
4.2 +++ b/Server/FormMain.cs Wed Aug 17 13:41:26 2016 +0200
4.3 @@ -3065,13 +3065,23 @@
4.4
4.5 private async Task ConnectHarmonyAsync()
4.6 {
4.7 + if (Program.HarmonyClient != null)
4.8 + {
4.9 + Program.HarmonyClient.Close();
4.10 + }
4.11 +
4.12 + //Reset Harmony client & config
4.13 + Program.HarmonyClient = null;
4.14 + Program.HarmonyConfig = null;
4.15 +
4.16 Console.WriteLine("Harmony: Connecting... ");
4.17 + Program.HarmonyClient = new HarmonyHub.Client(iTextBoxHarmonyHubAddress.Text);
4.18 //First create our client and login
4.19 if (File.Exists("SessionToken"))
4.20 {
4.21 var sessionToken = File.ReadAllText("SessionToken");
4.22 Console.WriteLine("Harmony: Reusing token: {0}", sessionToken);
4.23 - Program.HarmonyClient = HarmonyHub.HarmonyClient.Create(iTextBoxHarmonyHubAddress.Text, sessionToken);
4.24 + Program.HarmonyClient.Open(sessionToken);
4.25 }
4.26 else
4.27 {
4.28 @@ -3082,15 +3092,15 @@
4.29 }
4.30
4.31 Console.WriteLine("Harmony: Authenticating with Logitech servers...");
4.32 - Program.HarmonyClient = await HarmonyHub.HarmonyClient.Create(iTextBoxHarmonyHubAddress.Text, iTextBoxLogitechUserName.Text, iTextBoxLogitechPassword.Text);
4.33 + await Program.HarmonyClient.Open(iTextBoxLogitechUserName.Text, iTextBoxLogitechPassword.Text);
4.34 File.WriteAllText("SessionToken", Program.HarmonyClient.Token);
4.35 }
4.36
4.37 Console.WriteLine("Harmony: Fetching Harmony Hub configuration...");
4.38
4.39 //Fetch our config
4.40 - var harmonyConfig = await Program.HarmonyClient.GetConfigAsync();
4.41 - PopulateTreeViewHarmony(harmonyConfig);
4.42 + Program.HarmonyConfig = await Program.HarmonyClient.GetConfigAsync();
4.43 + PopulateTreeViewHarmony(Program.HarmonyConfig);
4.44
4.45 Console.WriteLine("Harmony: Ready");
4.46 }
4.47 @@ -3099,21 +3109,21 @@
4.48 ///
4.49 /// </summary>
4.50 /// <param name="aConfig"></param>
4.51 - private void PopulateTreeViewHarmony(HarmonyHub.Entities.Response.Config aConfig)
4.52 + private void PopulateTreeViewHarmony(HarmonyHub.Config aConfig)
4.53 {
4.54 iTreeViewHarmony.Nodes.Clear();
4.55 //Add our devices
4.56 - foreach (HarmonyHub.Entities.Response.Device device in aConfig.Devices)
4.57 + foreach (HarmonyHub.Device device in aConfig.Devices)
4.58 {
4.59 TreeNode deviceNode = iTreeViewHarmony.Nodes.Add(device.Id, $"{device.Label} ({device.DeviceTypeDisplayName}/{device.Model})");
4.60 deviceNode.Tag = device;
4.61
4.62 - foreach (HarmonyHub.Entities.Response.ControlGroup cg in device.ControlGroups)
4.63 + foreach (HarmonyHub.ControlGroup cg in device.ControlGroups)
4.64 {
4.65 TreeNode cgNode = deviceNode.Nodes.Add(cg.Name);
4.66 cgNode.Tag = cg;
4.67
4.68 - foreach (HarmonyHub.Entities.Response.Function f in cg.Functions)
4.69 + foreach (HarmonyHub.Function f in cg.Functions)
4.70 {
4.71 TreeNode fNode = cgNode.Nodes.Add(f.Name);
4.72 fNode.Tag = f;
4.73 @@ -3127,11 +3137,11 @@
4.74 private async void iTreeViewHarmony_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
4.75 {
4.76 //Upon function node double click we execute it
4.77 - var tag = e.Node.Tag as HarmonyHub.Entities.Response.Function;
4.78 - if (tag != null && e.Node.Parent.Parent.Tag is HarmonyHub.Entities.Response.Device)
4.79 + var tag = e.Node.Tag as HarmonyHub.Function;
4.80 + if (tag != null && e.Node.Parent.Parent.Tag is HarmonyHub.Device)
4.81 {
4.82 - HarmonyHub.Entities.Response.Function f = tag;
4.83 - HarmonyHub.Entities.Response.Device d = (HarmonyHub.Entities.Response.Device)e.Node.Parent.Parent.Tag;
4.84 + HarmonyHub.Function f = tag;
4.85 + HarmonyHub.Device d = (HarmonyHub.Device)e.Node.Parent.Parent.Tag;
4.86
4.87 Console.WriteLine($"Harmony: Sending {f.Name} to {d.Label}...");
4.88
5.1 --- a/Server/Program.cs Tue Aug 16 12:59:32 2016 +0200
5.2 +++ b/Server/Program.cs Wed Aug 17 13:41:26 2016 +0200
5.3 @@ -20,7 +20,6 @@
5.4 using System;
5.5 using System.Windows.Forms;
5.6 using System.Security.Principal;
5.7 -using HarmonyHub;
5.8
5.9
5.10 namespace SharpDisplayManager
5.11 @@ -31,8 +30,17 @@
5.12 //That is what we want but we should enforce it somehow.
5.13 public static FormMain iFormMain;
5.14
5.15 - //
5.16 - public static HarmonyClient HarmonyClient { get; set; }
5.17 + /// <summary>
5.18 + ///
5.19 + /// </summary>
5.20 + public static HarmonyHub.Client HarmonyClient { get; set; }
5.21 +
5.22 + /// <summary>
5.23 + ///
5.24 + /// </summary>
5.25 + public static HarmonyHub.Config HarmonyConfig { get; set; }
5.26 +
5.27 +
5.28 /// <summary>
5.29 /// The main entry point for the application.
5.30 /// </summary>
6.1 --- a/Server/SharpDisplayManager.csproj Tue Aug 16 12:59:32 2016 +0200
6.2 +++ b/Server/SharpDisplayManager.csproj Wed Aug 17 13:41:26 2016 +0200
6.3 @@ -112,7 +112,7 @@
6.4 <Private>True</Private>
6.5 </Reference>
6.6 <Reference Include="HarmonyHub, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
6.7 - <HintPath>..\packages\SharpLibHarmony.0.2.1\lib\net451\HarmonyHub.dll</HintPath>
6.8 + <HintPath>..\packages\SharpLibHarmony.0.3.0\lib\net451\HarmonyHub.dll</HintPath>
6.9 <Private>True</Private>
6.10 </Reference>
6.11 <Reference Include="LibCecSharp, Version=2.2.0.0, Culture=neutral, processorArchitecture=x86">
6.12 @@ -173,6 +173,7 @@
6.13 <Compile Include="Actions\ActionCecDeviceStandby.cs" />
6.14 <Compile Include="Actions\ActionCecUserControlReleased.cs" />
6.15 <Compile Include="Actions\ActionDisplayMessage.cs" />
6.16 + <Compile Include="Actions\ActionHarmonyCommand.cs" />
6.17 <Compile Include="CbtHook.cs" />
6.18 <Compile Include="CecClient.cs" />
6.19 <Compile Include="ConsumerElectronicControl.cs" />
7.1 --- a/Server/packages.config Tue Aug 16 12:59:32 2016 +0200
7.2 +++ b/Server/packages.config Wed Aug 17 13:41:26 2016 +0200
7.3 @@ -4,7 +4,7 @@
7.4 <package id="Loamen.agsXMPP" version="1.3.1" targetFramework="net46" />
7.5 <package id="NAudio" version="1.7.3" targetFramework="net45" />
7.6 <package id="SharpLibDisplay" version="0.2.5" targetFramework="net46" />
7.7 - <package id="SharpLibHarmony" version="0.2.1" targetFramework="net46" />
7.8 + <package id="SharpLibHarmony" version="0.3.0" targetFramework="net46" />
7.9 <package id="SharpLibHid" version="1.4.2" targetFramework="net46" />
7.10 <package id="SharpLibNotification" version="0.0.1" targetFramework="net46" />
7.11 <package id="SharpLibWin32" version="0.0.9" targetFramework="net46" />