diff --git a/csharp/Sinexcel 12K TL/SinexcelRecord.Api.cs b/csharp/Sinexcel 12K TL/SinexcelRecord.Api.cs index 7d6909d9e..50905a5b7 100644 --- a/csharp/Sinexcel 12K TL/SinexcelRecord.Api.cs +++ b/csharp/Sinexcel 12K TL/SinexcelRecord.Api.cs @@ -1,5 +1,3 @@ -using System.Diagnostics.CodeAnalysis; -using System.Globalization; using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType; using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units.Power; @@ -9,6 +7,7 @@ namespace InnovEnergy.Lib.Devices.Sinexcel_12K_TL; public partial class SinexcelRecord { + private Int16 _factorFromKwtoW = 1000; // ─────────────────────────────────────────────── // Public API — Decoded Float Values // ─────────────────────────────────────────────── @@ -30,17 +29,17 @@ public partial class SinexcelRecord public Current GridCPhaseCurrent => UIntToFloat(_grid_C_Phase_Current); public Current GridNWireCurrent => UIntToFloat(_grid_N_Wire_Current); - public ApparentPower GridAPhaseApparentPower => UIntToFloat(_gridAPhaseApparentPower); - public ApparentPower GridBPhaseApparentPower => UIntToFloat(_gridBPhaseApparentPower); - public ApparentPower GridCPhaseApparentPower => UIntToFloat(_gridCPhaseApparentPower); + public ApparentPower GridAPhaseApparentPower => UIntToFloat(_gridAPhaseApparentPower) * _factorFromKwtoW; + public ApparentPower GridBPhaseApparentPower => UIntToFloat(_gridBPhaseApparentPower) * _factorFromKwtoW; + public ApparentPower GridCPhaseApparentPower => UIntToFloat(_gridCPhaseApparentPower) * _factorFromKwtoW; - public ActivePower GridAPhaseActivePower => UIntToFloat(_gridAPhaseActivePower); - public ActivePower GridBPhaseActivePower => UIntToFloat(_gridBPhaseActivePower); - public ActivePower GridCPhaseActivePower => UIntToFloat(_gridCPhaseActivePower); + public ActivePower GridAPhaseActivePower => UIntToFloat(_gridAPhaseActivePower) * _factorFromKwtoW; + public ActivePower GridBPhaseActivePower => UIntToFloat(_gridBPhaseActivePower) * _factorFromKwtoW; + public ActivePower GridCPhaseActivePower => UIntToFloat(_gridCPhaseActivePower) * _factorFromKwtoW; - public ReactivePower GridAPhaseReactivePower => UIntToFloat(_gridAPhaseReactivePower); - public ReactivePower GridBPhaseReactivePower => UIntToFloat(_gridBPhaseReactivePower); - public ReactivePower GridCPhaseReactivePower => UIntToFloat(_gridCPhaseReactivePower); + public ReactivePower GridAPhaseReactivePower => UIntToFloat(_gridAPhaseReactivePower) * _factorFromKwtoW; + public ReactivePower GridBPhaseReactivePower => UIntToFloat(_gridBPhaseReactivePower) * _factorFromKwtoW; + public ReactivePower GridCPhaseReactivePower => UIntToFloat(_gridCPhaseReactivePower) * _factorFromKwtoW; // ─────────────────────────────────────────────── // Load Measurements @@ -60,17 +59,19 @@ public partial class SinexcelRecord public Current LoadCPhaseCurrent => UIntToFloat(_loadCPhaseCurrent); public Current LoadNWireCurrent => UIntToFloat(_loadNWireCurrent); - public ApparentPower LoadAPhaseApparentPower => UIntToFloat(_loadAPhaseApparentPower); - public ApparentPower LoadBPhaseApparentPower => UIntToFloat(_loadBPhaseApparentPower); - public ApparentPower LoadCPhaseApparentPower => UIntToFloat(_loadCPhaseApparentPower); + public ApparentPower LoadAPhaseApparentPower => UIntToFloat(_loadAPhaseApparentPower) * _factorFromKwtoW; + public ApparentPower LoadBPhaseApparentPower => UIntToFloat(_loadBPhaseApparentPower) * _factorFromKwtoW; + public ApparentPower LoadCPhaseApparentPower => UIntToFloat(_loadCPhaseApparentPower) * _factorFromKwtoW; - public ActivePower LoadAPhaseActivePower => UIntToFloat(_loadAPhaseActivePower); - public ActivePower LoadBPhaseActivePower => UIntToFloat(_loadBPhaseActivePower); - public ActivePower LoadCPhaseActivePower => UIntToFloat(_loadCPhaseActivePower); + public ActivePower LoadAPhaseActivePower => UIntToFloat(_loadAPhaseActivePower) * _factorFromKwtoW; + public ActivePower LoadBPhaseActivePower => UIntToFloat(_loadBPhaseActivePower) * _factorFromKwtoW; + public ActivePower LoadCPhaseActivePower => UIntToFloat(_loadCPhaseActivePower) * _factorFromKwtoW; + + public ActivePower ConsumptionPower => TotalLoadPower; - public ReactivePower LoadAPhaseReactivePower => UIntToFloat(_loadAPhaseReactivePower); - public ReactivePower LoadBPhaseReactivePower => UIntToFloat(_loadBPhaseReactivePower); - public ReactivePower LoadCPhaseReactivePower => UIntToFloat(_loadCPhaseReactivePower); + public ReactivePower LoadAPhaseReactivePower => UIntToFloat(_loadAPhaseReactivePower) * _factorFromKwtoW; + public ReactivePower LoadBPhaseReactivePower => UIntToFloat(_loadBPhaseReactivePower) * _factorFromKwtoW; + public ReactivePower LoadCPhaseReactivePower => UIntToFloat(_loadCPhaseReactivePower) * _factorFromKwtoW; // ─────────────────────────────────────────────── // Inverter Measurements @@ -83,10 +84,12 @@ public partial class SinexcelRecord public Voltage InverterBcWireVoltage => UIntToFloat(_inverterBCWireVoltage); public Voltage InverterCaWireVoltage => UIntToFloat(_inverterCAWireVoltage); - public ActivePower InverterAPhaseActivePower => UIntToFloat(_inverterAPhaseActivePower); - public ActivePower InverterBPhaseActivePower => UIntToFloat(_inverterBPhaseActivePower); - public ActivePower InverterCPhaseActivePower => UIntToFloat(_inverterCPhaseActivePower); + public ActivePower InverterAPhaseActivePower => UIntToFloat(_inverterAPhaseActivePower) * _factorFromKwtoW; + public ActivePower InverterBPhaseActivePower => UIntToFloat(_inverterBPhaseActivePower) * _factorFromKwtoW; + public ActivePower InverterCPhaseActivePower => UIntToFloat(_inverterCPhaseActivePower) * _factorFromKwtoW; + public ActivePower InverterActivePower => InverterAPhaseActivePower + InverterBPhaseActivePower + InverterCPhaseActivePower; + // ─────────────────────────────────────────────── // DC/AC Temperature Sensors (°C) // ─────────────────────────────────────────────── @@ -99,22 +102,24 @@ public partial class SinexcelRecord // ─────────────────────────────────────────────── // Date / Time Information // ─────────────────────────────────────────────── - public Single Year => UIntToFloat(_year); - public Single Month => UIntToFloat(_month); - public Single Day => UIntToFloat(_day); - public Single Hour => UIntToFloat(_hour); - public Single Minute => UIntToFloat(_minute); - public Single Second => UIntToFloat(_second); - + public UInt16 Year => (UInt16) ConvertBitPatternToFloat(_year); + public UInt16 Month => (UInt16) ConvertBitPatternToFloat(_month); + public UInt16 Day => (UInt16) ConvertBitPatternToFloat(_day); + public UInt16 Hour => (UInt16) ConvertBitPatternToFloat(_hour); + public UInt16 Minute => (UInt16) ConvertBitPatternToFloat(_minute); + public UInt16 Second => (UInt16) ConvertBitPatternToFloat(_second); + + public DateTime SystemDateTime => new(Year, Month, Day, Hour, Minute, Second); + // ─────────────────────────────────────────────── // Diesel Generator Measurements // ─────────────────────────────────────────────── public Voltage DieselGenAPhaseVoltage => ConvertBitPatternToFloat(_dieselGenAPhaseVoltage); public Voltage DieselGenBPhaseVoltage => ConvertBitPatternToFloat(_dieselGenBPhaseVoltage); public Voltage DieselGenCPhaseVoltage => ConvertBitPatternToFloat(_dieselGenCPhaseVoltage); - public Voltage DieselGenABWireVoltage => ConvertBitPatternToFloat(_dieselGenABWireVoltage); - public Voltage DieselGenBCWireVoltage => ConvertBitPatternToFloat(_dieselGenBCWireVoltage); - public Voltage DieselGenCAWireVoltage => ConvertBitPatternToFloat(_dieselGenCAWireVoltage); + public Voltage DieselGenAbWireVoltage => ConvertBitPatternToFloat(_dieselGenABWireVoltage); + public Voltage DieselGenBcWireVoltage => ConvertBitPatternToFloat(_dieselGenBCWireVoltage); + public Voltage DieselGenCaWireVoltage => ConvertBitPatternToFloat(_dieselGenCAWireVoltage); public Frequency DieselGenVoltageFrequency => ConvertBitPatternToFloat(_dieselGenVoltageFrequency); @@ -123,38 +128,39 @@ public partial class SinexcelRecord public Current DieselGenCPhaseCurrent => ConvertBitPatternToFloat(_dieselGenCPhaseCurrent); public Current DieselGenNWireCurrent => ConvertBitPatternToFloat(_dieselGenNWireCurrent); - public ApparentPower DieselGenAPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenAPhaseApparentPower); - public ApparentPower DieselGenBPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenBPhaseApparentPower); - public ApparentPower DieselGenCPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenCPhaseApparentPower); + public ApparentPower DieselGenAPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenAPhaseApparentPower) * _factorFromKwtoW; + public ApparentPower DieselGenBPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenBPhaseApparentPower) * _factorFromKwtoW; + public ApparentPower DieselGenCPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenCPhaseApparentPower) * _factorFromKwtoW; - public ActivePower DieselGenAPhaseActivePower => ConvertBitPatternToFloat(_dieselGenAPhaseActivePower); - public ActivePower DieselGenBPhaseActivePower => ConvertBitPatternToFloat(_dieselGenBPhaseActivePower); - public ActivePower DieselGenCPhaseActivePower => ConvertBitPatternToFloat(_dieselGenCPhaseActivePower); + public ActivePower DieselGenAPhaseActivePower => ConvertBitPatternToFloat(_dieselGenAPhaseActivePower) * _factorFromKwtoW; + public ActivePower DieselGenBPhaseActivePower => ConvertBitPatternToFloat(_dieselGenBPhaseActivePower) * _factorFromKwtoW; + public ActivePower DieselGenCPhaseActivePower => ConvertBitPatternToFloat(_dieselGenCPhaseActivePower) * _factorFromKwtoW; - public ReactivePower DieselGenAPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenAPhaseReactivePower); - public ReactivePower DieselGenBPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenBPhaseReactivePower); - public ReactivePower DieselGenCPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenCPhaseReactivePower); + public ReactivePower DieselGenAPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenAPhaseReactivePower) * _factorFromKwtoW; + public ReactivePower DieselGenBPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenBPhaseReactivePower) * _factorFromKwtoW; + public ReactivePower DieselGenCPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenCPhaseReactivePower) * _factorFromKwtoW; // ─────────────────────────────────────────────── // Photovoltaic and Battery Measurements // ─────────────────────────────────────────────── public Voltage PvVoltage1 => ConvertBitPatternToFloat(_pvVoltage1); public Current PvCurrent1 => ConvertBitPatternToFloat(_pvCurrent1); - public ActivePower PvPower1 => ConvertBitPatternToFloat(_pvPower1); + public ActivePower PvPower1 => ConvertBitPatternToFloat(_pvPower1) *_factorFromKwtoW; public Voltage PvVoltage2 => ConvertBitPatternToFloat(_pvVoltage2); public Current PvCurrent2 => ConvertBitPatternToFloat(_pvCurrent2); - public ActivePower PvPower2 => ConvertBitPatternToFloat(_pvPower2); + public ActivePower PvPower2 => ConvertBitPatternToFloat(_pvPower2) * _factorFromKwtoW; + - public Voltage BatteryVoltage1 => ConvertBitPatternToFloat(_batteryVoltage1); - public Current BatteryCurrent1 => ConvertBitPatternToFloat(_batteryCurrent1); - public ActivePower BatteryPower1 => ConvertBitPatternToFloat(_batteryPower1); - public Percent BatterySoc1 => ConvertBitPatternToFloat(_batterySoc1); - public float BatteryFullLoadDuration1 => ConvertBitPatternToFloat(_batteryFullLoadDuration1); + public Voltage Battery1Voltage => ConvertBitPatternToFloat(_batteryVoltage1); + public Current Battery1Current => ConvertBitPatternToFloat(_batteryCurrent1); + public ActivePower Battery1Power => ConvertBitPatternToFloat(_batteryPower1) * _factorFromKwtoW; + public Percent Battery1Soc => ConvertBitPatternToFloat(_batterySoc1); + public float BatteryFullLoadDuration1 => ConvertBitPatternToFloat(_batteryFullLoadDuration1); // this is in hour - public Voltage BatteryVoltage2 => ConvertBitPatternToFloat(_batteryVoltage2); - public Current BatteryCurrent2 => ConvertBitPatternToFloat(_batteryCurrent2); - public ActivePower BatteryPower2 => ConvertBitPatternToFloat(_batteryPower2); - public Percent BatterySoc2 => ConvertBitPatternToFloat(_batterySoc2); + public Voltage Battery2Voltage => ConvertBitPatternToFloat(_batteryVoltage2); + public Current Battery2Current => ConvertBitPatternToFloat(_batteryCurrent2); + public ActivePower Battery2Power => ConvertBitPatternToFloat(_batteryPower2) * _factorFromKwtoW; + public Percent Battery2Soc => ConvertBitPatternToFloat(_batterySoc2); public float BatteryFullLoadDuration2 => ConvertBitPatternToFloat(_batteryFullLoadDuration2); public Temperature DcdcTemperature1 => ConvertBitPatternToFloat(_dcdcTemperature1); @@ -166,8 +172,8 @@ public partial class SinexcelRecord // ─────────────────────────────────────────────── // Energy and Power Summary // ─────────────────────────────────────────────── - public Energy ElectricityPurchased => ConvertBitPatternToFloat(_electricityPurchased); - public Energy ElectricityFed => ConvertBitPatternToFloat(_electricityFed); + public Energy TotalEnergyToUser => ConvertBitPatternToFloat(_electricityPurchased); + public Energy TotalEnergyToGrid => ConvertBitPatternToFloat(_electricityFed); public Energy SelfGeneratedElectricity => ConvertBitPatternToFloat(_selfGeneratedElectricity); public Energy BatteryCharge => ConvertBitPatternToFloat(_batteryCharge); public Energy BatteryDischarge => ConvertBitPatternToFloat(_batteryDischarge); @@ -175,21 +181,21 @@ public partial class SinexcelRecord public Energy DailySelfGeneratedElectricity => ConvertBitPatternToFloat(_dailySelfGeneratedElectricity); public Energy DailyElectricityPurchased => ConvertBitPatternToFloat(_dailyElectricityPurchased); public Energy DailyElectricityFed => ConvertBitPatternToFloat(_dailyElectricityFed); - public Energy DailyBatteryCharge => ConvertBitPatternToFloat(_dailyBatteryCharge); - public Energy DailyBatteryDischarge => ConvertBitPatternToFloat(_dailyBatteryDischarge); + public Energy BatteryDailyChargeEnergy => ConvertBitPatternToFloat(_dailyBatteryCharge); + public Energy BatteryDailyDischargeEnergy => ConvertBitPatternToFloat(_dailyBatteryDischarge); public Energy DailyLoadPowerConsumption => ConvertBitPatternToFloat(_dailyLoadPowerConsumption); - public ActivePower TotalPhotovoltaicPower => ConvertBitPatternToFloat(_totalPhotovoltaicPower); - public ActivePower TotalBatteryPower => ConvertBitPatternToFloat(_totalBatteryPower); - public ActivePower TotalLoadPower => ConvertBitPatternToFloat(_totalLoadPower); - public ActivePower TotalGridPower => ConvertBitPatternToFloat(_totalGridPower); - public ActivePower ImportantLoadTotalPower => ConvertBitPatternToFloat(_importantLoadTotalPower); - public ActivePower GeneralLoadTotalPower => ConvertBitPatternToFloat(_generalLoadTotalPower); + public ActivePower TotalPhotovoltaicPower => ConvertBitPatternToFloat(_totalPhotovoltaicPower) * _factorFromKwtoW; + public ActivePower TotalBatteryPower => ConvertBitPatternToFloat(_totalBatteryPower) * _factorFromKwtoW; + public ActivePower TotalLoadPower => ConvertBitPatternToFloat(_totalLoadPower) * _factorFromKwtoW ; + public ActivePower TotalGridPower => ConvertBitPatternToFloat(_totalGridPower) * _factorFromKwtoW ; + public ActivePower ImportantLoadTotalPower => ConvertBitPatternToFloat(_importantLoadTotalPower)* _factorFromKwtoW; + public ActivePower GeneralLoadTotalPower => ConvertBitPatternToFloat(_generalLoadTotalPower)* _factorFromKwtoW; public Voltage Pv3Voltage => ConvertBitPatternToFloat(_pv3Voltage); public Current Pv3Current => ConvertBitPatternToFloat(_pv3Current); - public ActivePower Pv3Power => ConvertBitPatternToFloat(_pv3Power); + public ActivePower Pv3Power => ConvertBitPatternToFloat(_pv3Power) * _factorFromKwtoW; public Voltage Pv4Voltage => ConvertBitPatternToFloat(_pv4Voltage); public Current Pv4Current => ConvertBitPatternToFloat(_pv4Current); - public ActivePower Pv4Power => ConvertBitPatternToFloat(_pv4Power); + public ActivePower Pv4Power => ConvertBitPatternToFloat(_pv4Power) * _factorFromKwtoW; public ActivePower GeneratorTotalPower => ConvertBitPatternToFloat(_generatorTotalPower); // ─────────────────────────────────────────────── @@ -318,13 +324,13 @@ public partial class SinexcelRecord set => _batteryCapacity1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } - public float MaxChargingCurrentBattery1 + public float Battery1MaxChargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxChargingCurrentBattery1)); set => _maxChargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } - public float MaxDischargingCurrentBattery1 + public float Battery1MaxDischargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxDischargingCurrentBattery1)); set => _maxDischargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); @@ -336,7 +342,7 @@ public partial class SinexcelRecord set => _ratedBatteryVoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } - public float MinSocBattery1 + public float Battery1MinSoc { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_minSocBattery1)); set => _minSocBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); @@ -356,8 +362,8 @@ public partial class SinexcelRecord public float ActiveChargeDischargePower { - get => ConvertBitPatternToFloat(_activeChargeDischargePower); - set => _activeChargeDischargePower = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); + get => ConvertBitPatternToFloat(_activeChargeDischargePower) * _factorFromKwtoW; + set => _activeChargeDischargePower = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); // we should check this may need to convert from W to KW } // ─────────────────────────────────────────────── @@ -405,13 +411,13 @@ public partial class SinexcelRecord set => _battery2Capacity = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } - public float MaxChargingCurrentBattery2 + public float Battery2MaxChargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((int)_maxChargingCurrentBattery2)); set => _maxChargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } - public float MaxDischargingCurrentBattery2 + public float Battery2MaxDischargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((int)_maxDischargingCurrentBattery2)); set => _maxDischargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); @@ -498,16 +504,10 @@ public partial class SinexcelRecord set => _meterReverseManualDetection = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } - public Voltage BatteryVoltage + public SinexcelBatteryRating BatteryVoltageRating { - get => (Voltage)ConvertBitPatternToFloat(_batteryVoltage); - set => _batteryVoltage = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); - } - - public SinexcelBatteryRating BatteryRating - { - get => (SinexcelBatteryRating)ConvertBitPatternToFloat(_batteryRating); - set => _batteryRating = (UInt32)value; + get => (SinexcelBatteryRating)ConvertBitPatternToFloat(_batteryVoltageRating); + set => _batteryVoltageRating = (UInt32)value; } public float Battery1Activation @@ -571,23 +571,122 @@ public partial class SinexcelRecord // ─────────────────────────────────────────────── public ActivePower ElectricMeterAPhaseActivePower { - get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseActivePower)); + get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseActivePower)) * _factorFromKwtoW; } public ActivePower ElectricMeterBPhaseActivePower { - get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseActivePower)); + get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseActivePower)) * _factorFromKwtoW; } public ActivePower ElectricMeterCPhaseActivePower { - get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterCPhaseActivePower)); + get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterCPhaseActivePower)) * _factorFromKwtoW; } + public ActivePower GridPower + { + get => ElectricMeterAPhaseActivePower + ElectricMeterBPhaseActivePower + ElectricMeterCPhaseActivePower; + } + + /* + // Energy (kW·h) + public Energy Battery1TotalChargingEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1TotalChargingEnergy)); // 0xB0FC + public Energy Battery1TotalDischargedEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1TotalDischargedEnergy)); // 0xB0FE + + // Pack totals and status + public Voltage Battery1PackTotalVoltage => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1PackTotalVoltage)); // 0xB100 (0.01 V resolution per spec) + public Current Battery1PackTotalCurrent => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1PackTotalCurrent)); // 0xB102 (0.01 A resolution per spec) + public Temperature Battery1Temperature => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1Temperature)); // 0xB104 (0.01 °C resolution per spec) + public Percent Battery1SocSecondvalue => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1Soc)); // 0xB106 % + public Percent Battery1Soh => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1Soh)); // 0xB108 % + // Energy (kW·h) + public float Battery2TotalChargingEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2TotalChargingEnergy)); // 0xB1FC + public float Battery2TotalDischargedEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2TotalDischargedEnergy)); // 0xB1FE + +// Pack Voltage / Current / Temperature + public Voltage Battery2PackTotalVoltage => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2PackTotalVoltage)); // 0xB200 (0.01 V resolution) + public Current Battery2PackTotalCurrent => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2PackTotalCurrent)); // 0xB202 (0.01 A resolution) + public Temperature Battery2Socsecondvalue => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2Soc)); // 0xB206 % + public Percent Battery2Soh => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2Soh)); // 0xB208 % + + // Repetitive-week mask (bit-mapped 0–6 = Sun–Sat) + public SinexcelWeekDays RepetitiveWeeks + { + get => (SinexcelWeekDays)(_repetitiveWeeks & 0x7F); // only 7 bits used + set => _repetitiveWeeks = (UInt32)value; + } + + // Effective start / end as UNIX timestamps + public DateTime EffectiveStartDate + { + get => DateTimeOffset.FromUnixTimeSeconds(_effectiveStartDate).DateTime; + set => _effectiveStartDate = (UInt32)new DateTimeOffset(value).ToUnixTimeSeconds(); + } + + public DateTime EffectiveEndDate + { + get => DateTimeOffset.FromUnixTimeSeconds(_effectiveEndDate).DateTime; + set => _effectiveEndDate = (UInt32)new DateTimeOffset(value).ToUnixTimeSeconds(); + } + + // Charging power during time period 1 (kW) + public float ChargingPowerPeriod1 + { + get => BitConverter.Int32BitsToSingle(unchecked((Int32)_chargingPowerPeriod1)); + set => _chargingPowerPeriod1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); + } + + // ─────────────────────────────────────────────── + // Charging period 1 + // ─────────────────────────────────────────────── + public TimeSpan ChargeStartTimePeriod1 + { + get => ConvertToTimeSpan(_chargeStartTimePeriod1); + set => _chargeStartTimePeriod1 = ConvertFromTimeSpan(value); + } + + public TimeSpan ChargeEndTimePeriod1 + { + get => ConvertToTimeSpan(_chargeEndTimePeriod1); + set => _chargeEndTimePeriod1 = ConvertFromTimeSpan(value); + } + + // ─────────────────────────────────────────────── + // Discharging period 1 + // ─────────────────────────────────────────────── + public TimeSpan DischargeStartTimePeriod1 + { + get => ConvertToTimeSpan(_dischargeStartTimePeriod1); + set => _dischargeStartTimePeriod1 = ConvertFromTimeSpan(value); + } + + public TimeSpan DischargeEndTimePeriod1 + { + get => ConvertToTimeSpan(_dischargeEndTimePeriod1); + set => _dischargeEndTimePeriod1 = ConvertFromTimeSpan(value); + }*/ + + // ─────────────────────────────────────────────── // Conversion methodes // ─────────────────────────────────────────────── + + private static TimeSpan ConvertToTimeSpan(UInt32 value) + { + int hhmm = (int)value; + int hours = hhmm / 100; + int minutes = hhmm % 100; + return new TimeSpan(hours, minutes, 0); + } + + private static UInt32 ConvertFromTimeSpan(TimeSpan time) + { + int hhmm = time.Hours * 100 + time.Minutes; + return (UInt32)hhmm; + } + private static Single IntToFloat(Int32 intValue) { byte[] intBytes = BitConverter.GetBytes(intValue);