From 38e0b9701214c182238d00013a0984466e1e9546 Mon Sep 17 00:00:00 2001 From: Sparronator9999 <86388887+Sparronator9999@users.noreply.github.com> Date: Thu, 19 Dec 2024 06:56:40 +1100 Subject: [PATCH] Config updates, including breaking change - Add custom register config name (breaking change, since it is required) - Add enabled state to custom register configs (true by default for compatibility with older configs) - Add better config validation (this may render some previously "valid" configs invalid, even when adding custom register config names) - Some code doc updates --- YAMDCC.Config/ChargeLimitConf.cs | 10 +- YAMDCC.Config/FanConf.cs | 2 +- YAMDCC.Config/RegConf.cs | 20 +++- YAMDCC.Config/YAMDCC_Config.cs | 178 ++++++++++++++++++++++--------- 4 files changed, 151 insertions(+), 59 deletions(-) diff --git a/YAMDCC.Config/ChargeLimitConf.cs b/YAMDCC.Config/ChargeLimitConf.cs index 981ee94..658ddc9 100644 --- a/YAMDCC.Config/ChargeLimitConf.cs +++ b/YAMDCC.Config/ChargeLimitConf.cs @@ -19,30 +19,30 @@ namespace YAMDCC.Config { /// - /// Represents a charge threshold (a.k.a charge limit) config for a laptop. + /// Represents a charge limit config for a laptop. /// public sealed class ChargeLimitConf { /// - /// The register that controls the charge threshold. + /// The register that controls the charge limit. /// [XmlElement] public byte Reg { get; set; } /// - /// The value that corresponds to 0% battery threshold. + /// The value that corresponds to 0% charge limit (i.e. disabled). /// [XmlElement] public byte MinVal { get; set; } /// - /// The value that corresponds to 100% battery threshold. + /// The value that corresponds to 100% charge limit. /// [XmlElement] public byte MaxVal { get; set; } /// - /// The currently set Charge Threshold value. + /// The currently set charge limit value. /// [XmlElement] public byte CurVal { get; set; } diff --git a/YAMDCC.Config/FanConf.cs b/YAMDCC.Config/FanConf.cs index 3ec0e17..24bb496 100644 --- a/YAMDCC.Config/FanConf.cs +++ b/YAMDCC.Config/FanConf.cs @@ -24,7 +24,7 @@ namespace YAMDCC.Config public sealed class FanConf { /// - /// The display name of the fan in the curve editor. + /// The display name of the fan in the config editor. /// [XmlElement] public string Name { get; set; } diff --git a/YAMDCC.Config/RegConf.cs b/YAMDCC.Config/RegConf.cs index 89b2578..396b6a4 100644 --- a/YAMDCC.Config/RegConf.cs +++ b/YAMDCC.Config/RegConf.cs @@ -19,16 +19,28 @@ namespace YAMDCC.Config { /// - /// Represents miscellaneous register configurations for the target - /// system. May be required to enable fan control via YAMDCC. + /// Represents miscellaneous EC register configurations for the target + /// computer. May be required to enable fan control via YAMDCC. /// /// - /// All RegConfigs defined here will be applied on service start. + /// All RegConfs defined here will be applied on service start (unless disabled). /// public sealed class RegConf { /// - /// A description of what this config does. + /// Should this be applied? + /// + [XmlElement] + public bool Enabled { get; set; } = true; + + /// + /// A short name for this EC register config. + /// + [XmlElement] + public string Name { get; set; } + + /// + /// A longer description of what this config does. /// [XmlElement] public string Desc { get; set; } diff --git a/YAMDCC.Config/YAMDCC_Config.cs b/YAMDCC.Config/YAMDCC_Config.cs index 43d003e..9c723ba 100644 --- a/YAMDCC.Config/YAMDCC_Config.cs +++ b/YAMDCC.Config/YAMDCC_Config.cs @@ -112,17 +112,18 @@ public sealed class YAMDCC_Config /// A list of registers to write when applying a fan config. /// /// - /// May be null, but if not null, must have - /// at least one . + /// May be null or empty if not needed. /// [XmlArray] public RegConf[] RegConfs { get; set; } /// - /// Parses a YAMDCC config XML and returns an + /// Parses a YAMDCC config XML and returns a /// object. /// - /// The path to an XML config file. + /// + /// The path to an XML config file. + /// /// /// /// @@ -140,7 +141,9 @@ public static YAMDCC_Config Load(string xmlFile) /// /// Saves a YAMDCC config to the specified location. /// - /// The XML file to write to. + /// + /// The XML file to write to. + /// /// /// public void Save(string xmlFile) @@ -164,6 +167,7 @@ public void Save(string xmlFile) /// /// /// This does NOT guarantee the loaded config is valid! + /// (e.g. register values are not checked) /// /// /// true if the config is valid, otherwise false. @@ -188,76 +192,152 @@ private bool IsValid() // 1. Check if FanConfigs is not null // 2. Check if there's at least 1 FanConfig - if (FanConfs?.Length >= 1) + if (FanConfs?.Length < 1) { - for (int i = 0; i < FanConfs.Length; i++) + return false; + } + + for (int i = 0; i < FanConfs.Length; i++) + { + FanConf cfg = FanConfs[i]; + + if (string.IsNullOrEmpty(cfg.Name)) { - FanConf cfg = FanConfs[i]; + return false; + } - if (string.IsNullOrEmpty(cfg.Name)) - { - return false; - } + // YAMDCC doesn't handle MinSpeed lower than MaxSpeed, + // so return false if MinSpeed is lower or equal to MaxSpeed: + if (cfg.MinSpeed >= cfg.MaxSpeed) + { + return false; + } - // the selected fan curve shouldn't be higher than - // the number of fan curves in the config. - if (cfg.CurveSel >= FanConfs[i].FanCurveConfs.Length || - cfg.CurveSel < 0) - { - // if the fan profile selection is out of range, - // silently set it to 0 (the first fan curve) - // which should always exist: - cfg.CurveSel = 0; - } + // the selected fan curve shouldn't be higher than + // the number of fan curves in the config. + if (cfg.CurveSel >= FanConfs[i].FanCurveConfs.Length || + cfg.CurveSel < 0) + { + // if the fan profile selection is out of range, + // silently set it to 0 (the first fan curve) + // which should always exist: + cfg.CurveSel = 0; + } - if (cfg.UpThresholdRegs?.Length >= 1 && - cfg.DownThresholdRegs?.Length >= 1 && - cfg.FanCurveRegs?.Length >= 2 && - cfg.FanCurveConfs?.Length >= 1) - { - for (int j = 0; j < cfg.FanCurveConfs.Length; j++) - { - FanCurveConf curveCfg = cfg.FanCurveConfs[j]; - if (string.IsNullOrEmpty(curveCfg.Name) || - string.IsNullOrEmpty(curveCfg.Desc) || - // there should be exactly one temperature threshold - // per fan curve register; if there isn't, return false - curveCfg.TempThresholds?.Length != cfg.FanCurveRegs.Length) - { - return false; - } - } - } - else + // make sure that: + // - there is at least one each of up threshold, down threshold, + // and fan curve registers + // - there are the same amount of up threshold registers + // as down threshold registers + // - there is one more fan curve register than up/down threshold registers + // - there is at least one fan profile to apply (first should be Default) + if (cfg.UpThresholdRegs?.Length < 1 || + cfg.UpThresholdRegs?.Length != cfg.DownThresholdRegs?.Length || + cfg.FanCurveRegs?.Length != cfg.UpThresholdRegs?.Length + 1 || + cfg.FanCurveConfs?.Length < 1) + { + return false; + } + + for (int j = 0; j < cfg.FanCurveConfs.Length; j++) + { + FanCurveConf curveCfg = cfg.FanCurveConfs[j]; + if (string.IsNullOrEmpty(curveCfg.Name) || + string.IsNullOrEmpty(curveCfg.Desc) || + // there should be exactly one temperature threshold + // per fan curve register; if there isn't, return false + curveCfg.TempThresholds?.Length != cfg.FanCurveRegs.Length) { return false; } } } - else + + if (FullBlastConf is not null) { - return false; + // full blast mask shouldn't be 0, as that would make it impossible + // to change the full blast register's value when full blast toggled on/off + if (FullBlastConf.Mask == 0) + { + return false; + } } - // If the RegConfigs tag is defined in the XML, - // but has no elements, return false - if (RegConfs?.Length == 0) + if (ChargeLimitConf is not null) { - return false; + // YAMDCC cannot handle a lower min value than max value, + // so return false if that's the case for this config + if (ChargeLimitConf.MinVal >= ChargeLimitConf.MaxVal) + { + return false; + } + + // make sure charge limit to apply is within the config's + // defined bounds, but don't fail validation if it's not: + if (ChargeLimitConf.CurVal > ChargeLimitConf.MaxVal - ChargeLimitConf.MinVal) + { + ChargeLimitConf.CurVal = ChargeLimitConf.MaxVal; + } + else if (ChargeLimitConf.CurVal < 0) + { + ChargeLimitConf.CurVal = ChargeLimitConf.MinVal; + } } if (PerfModeConf is not null) { + if (PerfModeConf.PerfModes?.Length < 1) + { + return false; + } + // the selected performance mode shouldn't be higher than // the number of performance modes in the config if (PerfModeConf.ModeSel >= PerfModeConf.PerfModes.Length || PerfModeConf.ModeSel < 0) { - return false; + // same as fan profile selection, set the performance + // mode to the first available performance mode: + PerfModeConf.ModeSel = 0; + } + + for (int i = 0; i < PerfModeConf.PerfModes.Length; i++) + { + PerfMode perfMode = PerfModeConf.PerfModes[i]; + + if (string.IsNullOrEmpty(perfMode.Name) || + string.IsNullOrEmpty(perfMode.Desc)) + { + return false; + } + } + } + + if (KeySwapConf?.OnVal == KeySwapConf?.OffVal) + { + return false; + } + + if (KeyLightConf?.MinVal >= KeyLightConf?.MaxVal) + { + return false; + } + + if (RegConfs?.Length > 0) + { + for (int i = 0; i < RegConfs.Length; i++) + { + if (string.IsNullOrEmpty(RegConfs[i].Name) || + string.IsNullOrEmpty(RegConfs[i].Desc)) + { + return false; + } } } - // All other values are considered to be valid; return true + // All other values are considered to be valid; return true. + // Note that registers aren't checked and are (almost) always + // expected to be nonzero. return true; } }