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.
Announcement
Collapse
No announcement yet.
Yet another HSPI plugin library
Collapse
X
-
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
-
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
-
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:
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(" 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
-
And exactly the same applies to config pages UI, here's an example usage from my AKGoogleCast plugin config page:
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
-
Originally posted by alexbk66 View PostWhy was it a problem merging? Did you modify base classes?
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
-
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
-
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
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
-
Originally posted by Blob View PostI'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.
The only guess would be TriggersActions.cs calling DeSerialize() => Utils.DeSerializeObject()
Comment
-
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
-
Originally posted by Blob View PostI'm trying to find the latest mono version without the problem.
What the exact message? Is it "DeSerializing object:"?
Comment
Comment