Updating HarmonyHub to v0.3.0.
authorStephaneLenclud
Wed, 17 Aug 2016 13:41:26 +0200
changeset 2366ba20e02d04f
parent 235 ba14a29944c4
child 237 1a1c2ae3a29c
Updating HarmonyHub to v0.3.0.
Adding untested Harmony command action.
Server/Actions/ActionDisplayMessage.cs
Server/Actions/ActionHarmonyCommand.cs
Server/FormEditObject.cs
Server/FormMain.cs
Server/Program.cs
Server/SharpDisplayManager.csproj
Server/packages.config
     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" />