Open sp00n opened 3 months ago
Ok, after digging further, the new liquidctl version returns a string value for a status entry ("Fan x control mode"), whereas the DLL only expects float values there:
Log entry
:
28/05/2024 03:29:52: Newtonsoft.Json.JsonReaderException: Could not convert string to double: DC. Path '[0].status[0].value', line 1, position 229.
at Newtonsoft.Json.JsonReader.ReadDoubleString(String s)
at Newtonsoft.Json.JsonTextReader.FinishReadQuotedNumber(ReadType readType)
at Newtonsoft.Json.JsonTextReader.ReadAsDouble()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at FanControl.Liquidctl.LiquidctlCLIWrapper.ReadStatus()
at FanControl.Liquidctl.LiquidctlPlugin.Load(IPluginSensorsContainer _container)
at FanControl.Domain.BackendProviders.Plugin.PluginBackendProvider.Open()
Result from liquidctl --json --address {address} status
:
[
{
"address": "\\\\?\\HID#VID_1E71&PID_2011#7&3b3f9bd5&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}",
"bus": "hid",
"description": "NZXT RGB & Fan Controller (3+6 channels)",
"status": [
{
"key": "Fan 1 control mode",
"unit": "",
"value": "DC"
},
{
"key": "Fan 1 duty",
"unit": "%",
"value": 25
},
]
}
]
The class used for deserializing the result LiquidctlStatusJSON.cs
, which expects float as the value
type:
using System.Collections.Generic;
namespace FanControl.Liquidctl
{
public class LiquidctlStatusJSON
{
public class StatusRecord
{
public string key { get; set; }
public float? value { get; set; }
public string unit { get; set; }
}
public string bus { get; set; }
public string address { get; set; }
public string description { get; set; }
public List<StatusRecord> status { get; set; }
}
}
I fixed this issue by replacing public float? value { get; set; }
with public dynamic value { get; set; }
There are other issues however, the current plugin can't handle outputs for multiple fans, e.g. "Fan 1 speed", "Fan 2 speed", etc. I tried to fix this in my modded version, but since I have no real idea about C#, I'm not creating a PR for this. It seems to work though. https://github.com/sp00n/FanControl.Liquidctl
I have an NZXT Controller hub that apparently is not recognized by this plugin. Executing the included liquidctl.exe with
liquidctl.exe list --debug
also showed nothing (and a version number 0.0.0-unknown?), so I went to the liquidctl repository and downloaded and build the latest revision, which then did show two recognized units:I actually wanted to control the Fan Controller, so it should be fine, however the plugin still doesn't recognize anything in Fan Control after having replaced the liquidctl.exe with the newly built one. Do I need to compile the whole project again, or does the code of the DLL itself also need to be updated to support anything new that has been added to liquidtctl?