Innovenergy_trunk/csharp/Lib/Devices/Kaco92L3/KacoRecord.Api.cs

255 lines
9.7 KiB
C#

using InnovEnergy.Lib.Devices.Kaco92L3.DataType;
namespace InnovEnergy.Lib.Devices.Kaco92L3;
public partial class KacoRecord
{
private static float ScaleSunspec(Int16 value, Int16 sf)
{
// -32768 is SunSpec "not implemented"
if (value == -32768)
return float.NaN;
if (sf == 0)
return value;
return (float)(value * Math.Pow(10, sf));
}
private static float ScaleSunspec(UInt16 value, Int16 sf)
{
// interpret unsigned as signed when applying SF; range is the same
return ScaleSunspec(unchecked((Int16)value), sf);
}
private static Int16 UnscaleSunspecToInt16(float value, Int16 sf)
{
if (float.IsNaN(value) || float.IsInfinity(value))
return -32768; // "not implemented" / invalid
if (sf == 0)
return (Int16)Math.Round(value);
var raw = value / (float)Math.Pow(10, sf);
return (Int16)Math.Round(raw);
}
private static UInt16 UnscaleSunspecToUInt16(float value, Int16 sf)
{
var raw = UnscaleSunspecToInt16(value, sf);
return unchecked((UInt16)raw);
}
/****************************** High-level API for Model 64201 ****************************/
// ───────────────────────────────────────────────
// States & control
// ───────────────────────────────────────────────
// Header
public UInt16 BattCharId => _battCharId; // ID = 64202
public UInt16 BattCharLength => _battCharLength; // L = 6 + (RBCount * 8)
public ReuqestedState RequestedState
{
get => (ReuqestedState)_requestedState;
set => _requestedState = (UInt16)value;
}
public CurrentState CurrentState => (CurrentState)_currentState;
public ControlMode ControlMode
{
get => (ControlMode)_controlMode;
set => _controlMode = (UInt16)value;
}
public bool IsGridConnected => CurrentState == CurrentState.GridConnected;
public bool IsStandby => CurrentState == CurrentState.Standby;
public bool IsOff => CurrentState == CurrentState.Off;
// Watchdog seconds (no scale factor)
public UInt16 WatchdogSeconds
{
get => _watchdog;
set => _watchdog = value;
}
// ───────────────────────────────────────────────
// Setpoints (scaled)
// ───────────────────────────────────────────────
/// <summary>Active power setpoint in percent of WMax [%].</summary>
public float ActivePowerSetPercent
{
get => ScaleSunspec(_wSetPct, _wSetPctSf);
set => _wSetPct = UnscaleSunspecToInt16(value, _wSetPctSf);
}
/// <summary>Reactive power setpoint in percent of SMax [%].</summary>
public float ReactivePowerSetPercent
{
get => ScaleSunspec(_varWMaxSetPct, _varSetPctSf);
set => _varWMaxSetPct = UnscaleSunspecToInt16(value, _varSetPctSf);
}
// ───────────────────────────────────────────────
// Ramp parameters (scaled)
// ───────────────────────────────────────────────
/// <summary>Active power PT1 ramp time [s].</summary>
public float ActivePowerRampTimeSeconds
{
get => ScaleSunspec(_wParamRmpTms, _rmpTmsSf);
set => _wParamRmpTms = UnscaleSunspecToUInt16(value, _rmpTmsSf);
}
/// <summary>Active power ramp-down rate [% ref / min].</summary>
public float ActivePowerRampDownPercentPerMin
{
get => ScaleSunspec(_wParamRmpDecTmn, _rmpIncDecSf);
set => _wParamRmpDecTmn = UnscaleSunspecToUInt16(value, _rmpIncDecSf);
}
/// <summary>Active power ramp-up rate [% ref / min].</summary>
public float ActivePowerRampUpPercentPerMin
{
get => ScaleSunspec(_wParamRmpIncTmn, _rmpIncDecSf);
set => _wParamRmpIncTmn = UnscaleSunspecToUInt16(value, _rmpIncDecSf);
}
/// <summary>Reactive power PT1 ramp time [s].</summary>
public float ReactivePowerRampTimeSeconds
{
get => ScaleSunspec(_varParamRmpTms, _rmpTmsSf);
set => _varParamRmpTms = UnscaleSunspecToUInt16(value, _rmpTmsSf);
}
/// <summary>Reactive power ramp-down rate [% ref / min].</summary>
public float ReactivePowerRampDownPercentPerMin
{
get => ScaleSunspec(_varParamRmpDecTmn, _rmpIncDecSf);
set => _varParamRmpDecTmn = UnscaleSunspecToUInt16(value, _rmpIncDecSf);
}
/// <summary>Reactive power ramp-up rate [% ref / min].</summary>
public float ReactivePowerRampUpPercentPerMin
{
get => ScaleSunspec(_varParamRmpIncTmn, _rmpIncDecSf);
set => _varParamRmpIncTmn = UnscaleSunspecToUInt16(value, _rmpIncDecSf);
}
// Ramp enable flags
public EnableDisableEnum ActivePowerRampEnable
{
get => (EnableDisableEnum)_wParamEna;
set => _wParamEna = (UInt16)value;
}
public EnableDisableEnum ReactivePowerRampEnable
{
get => (EnableDisableEnum)_varParamEna;
set => _varParamEna = (UInt16)value;
}
// ───────────────────────────────────────────────
// Status / error (read-only enum views)
// ───────────────────────────────────────────────
//public VendorStateEnum VendorState => (VendorStateEnum)_stVnd;
//public PuStateEnum PuState => (PuStateEnum)_stPu;
public StatePcu PcuState => (StatePcu)_stPcu;
public ErrorPcu PcuError => (ErrorPcu)_errPcu;
public UInt16 BatteryCharVersion => _battCharVersion;
public UInt16 BatteryCharMinorVersion => _battCharVerMinor;
/// <summary>
/// Scale factor for battery voltages (V_SF).
/// </summary>
public Int16 BatteryVoltageScaleFactor => _battCharVSf;
/// <summary>
/// Scale factor for battery currents (A_SF).
/// </summary>
public Int16 BatteryCurrentScaleFactor => _battCharASf;
// Helper wrappers for scaled values
private float ScaleBattVoltage(UInt16 raw) => ScaleSunspec(raw, _battCharVSf);
private float ScaleBattCurrent(UInt16 raw) => ScaleSunspec(raw, _battCharASf);
private UInt16 UnscaleBattVoltage(float value) => UnscaleSunspecToUInt16(value, _battCharVSf);
private UInt16 UnscaleBattCurrent(float value) => UnscaleSunspecToUInt16(value, _battCharASf);
// ───────────────────────────────────────────────
// Battery discharge limits (scaled, RW)
// ───────────────────────────────────────────────
/// <summary>Minimum discharge voltage [V].</summary>
public float MinDischargeVoltage
{
get => ScaleBattVoltage(_disMinVRaw);
set => _disMinVRaw = UnscaleBattVoltage(value);
}
/// <summary>Maximum discharge current [A].</summary>
public float MaxDischargeCurrent
{
get => ScaleBattCurrent(_disMaxARaw);
set => _disMaxARaw = UnscaleBattCurrent(value);
}
/// <summary>Discharge cutoff current [A]. If discharge current falls below this, it disconnects (optional according to sheet).</summary>
public float DischargeCutoffCurrent
{
get => ScaleBattCurrent(_disCutoffARaw);
set => _disCutoffARaw = UnscaleBattCurrent(value);
}
// ───────────────────────────────────────────────
// Battery charge limits (scaled, RW)
// ───────────────────────────────────────────────
/// <summary>Maximum charge voltage [V].</summary>
public float MaxChargeVoltage
{
get => ScaleBattVoltage(_chaMaxVRaw);
set => _chaMaxVRaw = UnscaleBattVoltage(value);
}
/// <summary>Maximum charge current [A].</summary>
public float MaxChargeCurrent
{
get => ScaleBattCurrent(_chaMaxARaw);
set => _chaMaxARaw = UnscaleBattCurrent(value);
}
/// <summary>Charge cutoff current [A]. If charge current falls below this, it disconnects.</summary>
public float ChargeCutoffCurrent
{
get => ScaleBattCurrent(_chaCutoffARaw);
set => _chaCutoffARaw = UnscaleBattCurrent(value);
}
// ───────────────────────────────────────────────
// Limit enable flag
// ───────────────────────────────────────────────
/// <summary>
/// When EnLimit = 1, new battery limits are activated.
/// </summary>
public EnableDisableEnum BatteryLimitsEnable
{
get => (EnableDisableEnum)_enLimitRaw;
set => _enLimitRaw = (UInt16)value;
}
/// <summary>Convenience bool wrapper for EnLimit.</summary>
public bool BatteryLimitsEnabled
{
get => BatteryLimitsEnable == EnableDisableEnum.Enabled;
set => BatteryLimitsEnable = value ? EnableDisableEnum.Enabled : EnableDisableEnum.Disabled;
}
}