Announcement

Collapse
No announcement yet.

Yet another HSPI plugin library

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #31
    I committed my changes, but didn't update the usage examples yet. Try searching for StartPageTimer for now. It worked for me. I'll try to provide more details asap.

    Comment


      #32
      Thanks. It took some effort merging the commit into my code, but pagecommands are working now and the added abstract/virtual also helps a lot .
      Currently figuring out if the new settings base class suits me or not.

      Comment


        #33
        Settings Base class usage is pretty simple, here's an example:

        Code:
            public class Settings : MySettingsBase
            {
                public Settings(string IniFile, IHSApplication Hs) : base(IniFile, Hs)
                {
                }
        
                private string _ClientId;
                public string ClientId
                {
                    get => _ClientId;
                    set
                    {
                        _ClientId = value;
                        SaveVal("ClientId", _ClientId);
                    }
                }
        
        
                private string _ClientSecret;
                public string ClientSecret
                {
                    get => _ClientSecret;
                    set
                    {
                        _ClientSecret = value;
                        SaveVal("ClientSecret", _ClientSecret);
                    }
                }
        
        
                /// <summary>
                /// Reset GCal service time in seconds
                /// </summary>
                private int _ResetGCalTime;
                public int ResetGCalTime
                {
                    get => _ResetGCalTime;
                    set
                    {
                        _ResetGCalTime = value;
                        SaveVal("ResetGCalTime", _ResetGCalTime.ToString());
                    }
                }
        
                /// <summary>
                /// Reset GCal service memory size in Mb
                /// </summary>
                private int _MaxGCalMemory;
                public int MaxGCalMemory
                {
                    get => _MaxGCalMemory;
                    set
                    {
                        _MaxGCalMemory = value;
                        SaveVal("MaxGCalMemory", _MaxGCalMemory.ToString());
                    }
                }
        
        
                public override void Load()
                {
                    ResetGCalTime = LoadVal<int>(nameof(ResetGCalTime), 0);
                    MaxGCalMemory = LoadVal<int>(nameof(MaxGCalMemory), 0);
        
                    ClientSecret = LoadVal("ClientSecret");
                    ClientId = LoadVal("ClientId");
                }
        
                public override void Save()
                {
                    SaveVal(nameof(ResetGCalTime), ResetGCalTime);
                    SaveVal(nameof(MaxGCalMemory), MaxGCalMemory);
                    SaveVal(nameof(ClientSecret), ClientSecret);
                    SaveVal(nameof(ClientId), ClientId);
                    base.Save();
                }
        
            }
        }

        Comment


          #34
          Some new features in commit 4671775:

          * class MySettingsBase (see above)

          * Clean-up/Fix RegisterWebPage functionality

          * pageCommands.Add working, including StartPageTimer for config pages

          * Most interesting - created mapping controls to variable names for ProcessPostUI - for config pages and Triggers/Actions. This mapping links UI controls to corresponding variables to automatically update the variable when control value changes. This mostly eliminates the need for ProcessPostUI functions. See VariableMap class, FormCheckBox, FormTextBox<U>, FormTimePicker, RadioButtonEnum functions (in both PageBuilder class and BaseActTrigData class).

          Comment


            #35
            More on VariableMap class. It makes consistent creating UI for both Config pages and Trigger/Action UI.

            Example from my AKGoogleCalendar plugin - building Action UI:

            Click image for larger version

Name:	Capture2.PNG
Views:	203
Size:	107.2 KB
ID:	1314957

            FormDropDown and FormTextBox link created UI controls (DropDown and TextBox) to the variables (SelectedCalendarID and EventSummary). And ProcessPostUI function simply calls CheckVariables which updates the variables if controls values are changed:

            Code:
            public override string BuildUI(string uniqueControlId, IPlugInAPI.strTrigActInfo actInfo)
            {
                StringBuilder sb = new StringBuilder();
            
                // Calendar selection droplist
                sb.Append(" Calendar:");
                MyPairList calendars = (this.controller as Controller).GetCalendars(inclDayCal: false);
                sb.Append(FormDropDown(nameof(SelectedCalendarID), uniqueControlId, ref calendars, SelectedCalendarID, 150, blankText: "Select Calendar"));            
            
                // Event Color droplist
                sb.Append("&nbsp; Color:");
                if(colors==null)
                    colors = (this.controller as Controller).GetEventColors();
            
                sb.Append(FormDropDown(nameof(ColorID), uniqueControlId, ref colors, ColorID, 150, blankText: "Select Color"));
            
                // Show sample of selected color
                try
                {
                    sb.Append(ColorSample(ColorID));
                }
                catch (Exception) { }
            
                // Event Summary textbox
                sb.Append("</BR>With Text:");
                sb.Append(FormTextBox(nameof(EventSummary), uniqueControlId, "Event Summary", EventSummary));
            
                return sb.ToString();
            }
            Code:
            public override IPlugInAPI.strMultiReturn ProcessPostUI(NameValueCollection postData,
                    IPlugInAPI.strTrigActInfo actionInfo)
            {
                CheckVariables(postData);
            
                // Here the new ActionData instance is created via Serialization
                return MakeReturn(actionInfo, error: null);
            }

            Comment


              #36
              And exactly the same applies to config pages UI, here's an example usage from my AKGoogleCast plugin config page:

              Click image for larger version

Name:	Capture1.PNG
Views:	219
Size:	132.5 KB
ID:	1314955

              Code:
              public string ChromecastTable()
              {
                  DeviceCastRoot[] RootDevices = controller.RootDevices.Values.ToArray();
              
                  string tt = "Add new Chromecast device manually in case discovery doesn't work";
              
                  string[] hdr = { AddBtn("add", tt), "Enable", "Name", "Type", "IP", "Port", "Log", "ID" + (cnt % 2 == 0 ? "⌛" : " ") };
              
                  TableBuilder table = new TableBuilder( hdr,
                                                          page_name: PageLink,
                                                          klass: "full_width_table",
                                                          //width: "990px",
                                                          sorthdr: true,
                                                          sortby: sortby,
                                                          sortorder: sortorder,
                                                          tableID: "receivers_table",
                                                          inSlider: false
                                                          );
              
                  //Console.WriteLine($"{sortby} {sortorder}"); // TEMP
              
                  foreach (DeviceCastRoot device in RootDevices)
                  {
                      TableBuilder.TableRow row = table.AddRow();
              
                      // Get current status image
                      string img = device.Graphic;
                      if (String.IsNullOrEmpty(img))
                          img = device.StatusImageHtml();
                      img = PageBuilder.HTML_Img($"{img}", 32, 32);
              
                      row.AddCell(img);
              
                      row.AddCell(FormCheckBox(device.Enabled, nameof(device.Enabled), device));
                      row.AddCell(device.GetURL(display: device.Receiver?.FriendlyName));
                      row.AddCell(device.Receiver?.ModelName);
                      row.AddCell($"{device.Receiver?.IPEndPoint?.Address}");
                      row.AddCell($"{device.Receiver?.IPEndPoint?.Port}");
                      row.AddCell(FormCheckBox(device.log_enable, nameof(device.log_enable), device));
                      row.AddCell(device.Receiver?.Id);
                  }
              
                  return table.Build();
              }
              Code:
              public override string PostBackProc(NameValueCollection parts)
              {
                  // Check which control "id" caused postback
                  string ctrlID = parts.Get("id");
              
                  if (ctrlID == null)
                  {
                      // If it's timer callback - update chromecasts table
                      if (CheckTimerCallback(parts, value: ChromecastTable()))
                      {
                          cnt++;
                          return "";
                      }
                      else
                      {
                          CheckVariables(parts);
                      }
                  }
              }

              Comment


                #37
                Originally posted by Blob View Post
                Thanks. It took some effort merging the commit into my code.
                Why was it a problem merging? Did you modify base classes?

                Comment


                  #38
                  Originally posted by alexbk66 View Post
                  Why was it a problem merging? Did you modify base classes?
                  No, i did not change anything in de base (although I sometimes had to keep myself from doing so ).
                  I don't exactly remember the issues. maybe it had to do with my own classes. I changed a lot at the time trying to get pagecommands working.
                  Next time i will keep better track of any issues.

                  Comment


                    #39
                    Originally posted by Blob View Post
                    I sometimes had to keep myself from doing so )
                    if you have any improvement suggestions - feel free to contribute.

                    Comment


                      #40
                      Thanks, maybe i will.
                      Meantime i found myself needing a small change in pagebuilder:

                      Code:
                      FormTextBox<U>
                      //string unique = (parent is DeviceBase) ? (parent as DeviceBase).RefId.ToString() : "";
                      string unique = (parent is DeviceBase) ? (parent as DeviceBase).RefId.ToString() : parent.GetHashCode().ToString();

                      Comment


                        #41
                        I'm currently running in to a problem where i get the following error when submitting a configuration variable from trigger or action config:

                        Exception deserializing message: Object reference not set to an instance of an object
                        So exactly between BuildUI() and ProcessPostUI()

                        This only happens on Linux. In Windows everything works as expected.

                        Did you also encounter this and better yet, find some sort of solution?

                        Comment


                          #42
                          Originally posted by Blob View Post
                          I'm currently running in to a problem where i get the following error when submitting a configuration variable from trigger or action config:
                          So exactly between BuildUI() and ProcessPostUI() This only happens on Linux. In Windows everything works as expected.
                          Strange that it's different between Windows and Linux. Did you try creating a new trigger? Is it always the same problem? Is the error you are getting copied exactly from log file? Because I can't find anything in the source code.

                          The only guess would be TriggersActions.cs calling DeSerialize() => Utils.DeSerializeObject()

                          Comment


                            #43
                            Error does not appear in log. Only on console. That alone would not even be that bad, but off course the values are not getting updated :-)
                            Same thing happens when i compile a fresh copy of your example, so it should be reproducible if you want. (just click the checkbox in the sample action or trigger and watch console).

                            Seems mono related, as Installing a very old version solves the problem. I'm trying to find the latest mono version without the problem.

                            Comment


                              #44
                              Originally posted by Blob View Post
                              I'm trying to find the latest mono version without the problem.
                              It's better to troubleshoot and fix the problem - not trying older versions. Maybe even better to try Mono 6 preview, hopefully it fixes the problem too.

                              What the exact message? Is it "DeSerializing object:"?

                              Comment


                                #45
                                I committed some new changes and fixes 599f20c

                                Comment

                                Working...
                                X