using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType; using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units.Power; namespace InnovEnergy.Lib.Devices.Sinexcel_12K_TL; public partial class SinexcelRecord { private Int16 _factorFromKwtoW = 1000; // ─────────────────────────────────────────────── // Public API — Decoded Float Values // ─────────────────────────────────────────────── // ─────────────────────────────────────────────── // Grid Measurements // ─────────────────────────────────────────────── public Voltage GridAPhaseVoltage => ConvertBitPatternToFloat(_gridAPhaseVoltage); public Voltage GridBPhaseVoltage => UIntToFloat(_grid_B_Phase_Voltage); public Voltage GridCPhaseVoltage => UIntToFloat(_grid_C_Phase_Voltage); public Voltage GridAbWireVoltage => UIntToFloat(_grid_AB_Wire_Voltage); public Voltage GridBcWireVoltage => UIntToFloat(_grid_BC_Wire_Voltage); public Voltage GridCaWireVoltage => UIntToFloat(_grid_CA_Wire_Voltage); public Frequency GridVoltageFrequency => UIntToFloat(_grid_Voltage_Frequency); public Current GridAPhaseCurrent => UIntToFloat(_grid_A_Phase_Current); public Current GridBPhaseCurrent => UIntToFloat(_grid_B_Phase_Current); public Current GridCPhaseCurrent => UIntToFloat(_grid_C_Phase_Current); public Current GridNWireCurrent => UIntToFloat(_grid_N_Wire_Current); public ApparentPower GridAPhaseApparentPower => UIntToFloat(_gridAPhaseApparentPower) * _factorFromKwtoW; public ApparentPower GridBPhaseApparentPower => UIntToFloat(_gridBPhaseApparentPower) * _factorFromKwtoW; public ApparentPower GridCPhaseApparentPower => UIntToFloat(_gridCPhaseApparentPower) * _factorFromKwtoW; public ActivePower GridAPhaseActivePower => UIntToFloat(_gridAPhaseActivePower) * _factorFromKwtoW; public ActivePower GridBPhaseActivePower => UIntToFloat(_gridBPhaseActivePower) * _factorFromKwtoW; public ActivePower GridCPhaseActivePower => UIntToFloat(_gridCPhaseActivePower) * _factorFromKwtoW; public ReactivePower GridAPhaseReactivePower => UIntToFloat(_gridAPhaseReactivePower) * _factorFromKwtoW; public ReactivePower GridBPhaseReactivePower => UIntToFloat(_gridBPhaseReactivePower) * _factorFromKwtoW; public ReactivePower GridCPhaseReactivePower => UIntToFloat(_gridCPhaseReactivePower) * _factorFromKwtoW; // ─────────────────────────────────────────────── // Load Measurements // ─────────────────────────────────────────────── public Voltage LoadAPhaseVoltage => UIntToFloat(_loadAPhaseVoltage); public Voltage LoadBPhaseVoltage => UIntToFloat(_loadBPhaseVoltage); public Voltage LoadCPhaseVoltage => UIntToFloat(_loadCPhaseVoltage); public Voltage LoadAbWireVoltage => UIntToFloat(_loadABWireVoltage); public Voltage LoadBcWireVoltage => UIntToFloat(_loadBCWireVoltage); public Voltage LoadCaWireVoltage => UIntToFloat(_loadCAWireVoltage); public Frequency LoadVoltageFrequency => UIntToFloat(_loadVoltageFrequency); public Current LoadAPhaseCurrent => UIntToFloat(_loadAPhaseCurrent); public Current LoadBPhaseCurrent => UIntToFloat(_loadBPhaseCurrent); public Current LoadCPhaseCurrent => UIntToFloat(_loadCPhaseCurrent); public Current LoadNWireCurrent => UIntToFloat(_loadNWireCurrent); public ApparentPower LoadAPhaseApparentPower => UIntToFloat(_loadAPhaseApparentPower) * _factorFromKwtoW; public ApparentPower LoadBPhaseApparentPower => UIntToFloat(_loadBPhaseApparentPower) * _factorFromKwtoW; public ApparentPower LoadCPhaseApparentPower => UIntToFloat(_loadCPhaseApparentPower) * _factorFromKwtoW; 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) * _factorFromKwtoW; public ReactivePower LoadBPhaseReactivePower => UIntToFloat(_loadBPhaseReactivePower) * _factorFromKwtoW; public ReactivePower LoadCPhaseReactivePower => UIntToFloat(_loadCPhaseReactivePower) * _factorFromKwtoW; // ─────────────────────────────────────────────── // Inverter Measurements // ─────────────────────────────────────────────── public Voltage InverterAPhaseVoltage => UIntToFloat(_inverterAPhaseVoltage); public Voltage InverterBPhaseVoltage => UIntToFloat(_inverterBPhaseVoltage); public Voltage InverterCPhaseVoltage => UIntToFloat(_inverterCPhaseVoltage); public Voltage InverterAbWireVoltage => UIntToFloat(_inverterABWireVoltage); public Voltage InverterBcWireVoltage => UIntToFloat(_inverterBCWireVoltage); public Voltage InverterCaWireVoltage => UIntToFloat(_inverterCAWireVoltage); 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) // ─────────────────────────────────────────────── public Temperature DcacTemperature1 => UIntToFloat(_dcacTemperature1); public Temperature DcacTemperature2 => UIntToFloat(_dcacTemperature2); public Temperature DcacTemperature3 => UIntToFloat(_dcacTemperature3); public Temperature DcacTemperature4 => UIntToFloat(_dcacTemperature4); public Temperature DcacTemperature5 => UIntToFloat(_dcacTemperature5); // ─────────────────────────────────────────────── // Date / Time Information // ─────────────────────────────────────────────── 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 Frequency DieselGenVoltageFrequency => ConvertBitPatternToFloat(_dieselGenVoltageFrequency); public Current DieselGenAPhaseCurrent => ConvertBitPatternToFloat(_dieselGenAPhaseCurrent); public Current DieselGenBPhaseCurrent => ConvertBitPatternToFloat(_dieselGenBPhaseCurrent); public Current DieselGenCPhaseCurrent => ConvertBitPatternToFloat(_dieselGenCPhaseCurrent); public Current DieselGenNWireCurrent => ConvertBitPatternToFloat(_dieselGenNWireCurrent); public ApparentPower DieselGenAPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenAPhaseApparentPower) * _factorFromKwtoW; public ApparentPower DieselGenBPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenBPhaseApparentPower) * _factorFromKwtoW; public ApparentPower DieselGenCPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenCPhaseApparentPower) * _factorFromKwtoW; public ActivePower DieselGenAPhaseActivePower => ConvertBitPatternToFloat(_dieselGenAPhaseActivePower) * _factorFromKwtoW; public ActivePower DieselGenBPhaseActivePower => ConvertBitPatternToFloat(_dieselGenBPhaseActivePower) * _factorFromKwtoW; public ActivePower DieselGenCPhaseActivePower => ConvertBitPatternToFloat(_dieselGenCPhaseActivePower) * _factorFromKwtoW; 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) *_factorFromKwtoW; public Voltage PvVoltage2 => ConvertBitPatternToFloat(_pvVoltage2); public Current PvCurrent2 => ConvertBitPatternToFloat(_pvCurrent2); public ActivePower PvPower2 => ConvertBitPatternToFloat(_pvPower2) * _factorFromKwtoW; 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 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); public Temperature DcdcTemperature2 => ConvertBitPatternToFloat(_dcdcTemperature2); public Temperature DcdcTemperature3 => ConvertBitPatternToFloat(_dcdcTemperature3); public Temperature DcdcTemperature4 => ConvertBitPatternToFloat(_dcdcTemperature4); public Temperature DcdcTemperature5 => ConvertBitPatternToFloat(_dcdcTemperature5); // ─────────────────────────────────────────────── // Energy and Power Summary // ─────────────────────────────────────────────── 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); public Energy LoadPowerConsumption => ConvertBitPatternToFloat(_loadPowerConsumption); public Energy DailySelfGeneratedElectricity => ConvertBitPatternToFloat(_dailySelfGeneratedElectricity); public Energy DailyElectricityPurchased => ConvertBitPatternToFloat(_dailyElectricityPurchased); public Energy DailyElectricityFed => ConvertBitPatternToFloat(_dailyElectricityFed); public Energy BatteryDailyChargeEnergy => ConvertBitPatternToFloat(_dailyBatteryCharge); public Energy BatteryDailyDischargeEnergy => ConvertBitPatternToFloat(_dailyBatteryDischarge); public Energy DailyLoadPowerConsumption => ConvertBitPatternToFloat(_dailyLoadPowerConsumption); 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) * _factorFromKwtoW; public Voltage Pv4Voltage => ConvertBitPatternToFloat(_pv4Voltage); public Current Pv4Current => ConvertBitPatternToFloat(_pv4Current); public ActivePower Pv4Power => ConvertBitPatternToFloat(_pv4Power) * _factorFromKwtoW; public ActivePower GeneratorTotalPower => ConvertBitPatternToFloat(_generatorTotalPower); // ─────────────────────────────────────────────── // Manufacturer Information & Software Versions // ─────────────────────────────────────────────── public UInt16 ProtocolVersionNo => _protocolVersionNo; // 0x2000 public UInt16 DcacSoftwareVersionNo => _dcacSoftwareVersionNo; // 0x2001 public UInt16 DcdcSoftwareVersionNo => _dcdcSoftwareVersionNo; // 0x2002 public UInt16 ArmSoftwareVersionNo => _armSoftwareVersionNo; // 0x2003 public UInt16 CpldVersion => _cpldVersion; // 0x2004 public UInt16 AfciSoftwareVersionNo => _afciSoftwareVersionNo; // 0x2005 public SinexcelMachineType MachineType => (SinexcelMachineType)_machineType; // 0x2006 // ─────────────────────────────────────────────── // Device Info & Model // ─────────────────────────────────────────────── public ApparentPower RatedPowerKva => _ratedPower / 100f; // 0x2008 (value / 100) public SinexcelModel Model => (SinexcelModel)_model; // 0x200D public ThreePhaseWireSystem ThreePhaseWireSystem { get => (ThreePhaseWireSystem)_threePhaseWireSystem; set => _threePhaseWireSystem = (UInt32)value; } public InputFrequency InputFrequencyClass { get => (InputFrequency)_inputFrequencyClass; set => _inputFrequencyClass = (UInt32)value; } public WorkingMode WorkingMode { get => (WorkingMode)ConvertBitPatternToFloat(_workingMode); set => _workingMode = (UInt32)value; } public GridSwitchMethod GridSwitchMethod { get => (GridSwitchMethod)_methodSwitchMode; set => _methodSwitchMode = (UInt32)value; } // ─────────────────────────────────────────────── // Inverter Control Configuration // ─────────────────────────────────────────────── public SinexcelUnbalanceCompensation EnableOnGridUnbalanceCompensation { get => (SinexcelUnbalanceCompensation)_enableOnGridUnbalanceCompensation; set => _enableOnGridUnbalanceCompensation = (UInt32)value; } public SinexcelTemperatureDrop TemperatureDrop { get => (SinexcelTemperatureDrop)ConvertBitPatternToFloat(_temperatureDrop); set => _temperatureDrop = (UInt32)value; } public SinexcelHvrt Hvrt { get => (SinexcelHvrt)_hvrt; set => _hvrt = (UInt32)value; } public SinexcelLvrt Lvrt { get => (SinexcelLvrt)_lvrt; set => _lvrt = (UInt32)value; } // Fan Gear — numeric [0.5 ~ 1.0], default 1.0 public float FanGear { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_fanGear)); set => _fanGear = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } // ─────────────────────────────────────────────── // Battery Configuration // ─────────────────────────────────────────────── public SinexcelBatteryAccessMethod BatteryAccessMethod { get => (SinexcelBatteryAccessMethod)_batteryAccessMethod; set => _batteryAccessMethod = (UInt32)value; } public SinexcelMeterAccessEnable MeterAccessEnable { get => (SinexcelMeterAccessEnable)ConvertBitPatternToFloat(_meterAccessEnable); set => _meterAccessEnable = (UInt32)value; } public SinexcelBatteryEnable EnableBattery1 { get => (SinexcelBatteryEnable)ConvertBitPatternToFloat(_enableBattery1); set => _enableBattery1 = (UInt32)value; } public SinexcelBatteryEnable EnableBattery2 { get => (SinexcelBatteryEnable)ConvertBitPatternToFloat(_enableBattery2); set => _enableBattery2 = (UInt32)value; } public SinexcelPvEnable EnablePv1 { get => (SinexcelPvEnable)ConvertBitPatternToFloat(_enablePv1); set => _enablePv1 = (UInt32)value; } public SinexcelPvEnable EnablePv2 { get => (SinexcelPvEnable)ConvertBitPatternToFloat(_enablePv2); set => _enablePv2 = (UInt32)value; } public SinexcelBatteryType BatteryType { get => (SinexcelBatteryType)_batteryType; set => _batteryType = (UInt32)value; } public float BatteryCapacity1 { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCapacity1)); set => _batteryCapacity1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery1MaxChargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxChargingCurrentBattery1)); set => _maxChargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery1MaxDischargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxDischargingCurrentBattery1)); set => _maxDischargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float RatedBatteryVoltage1 { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_ratedBatteryVoltage1)); set => _ratedBatteryVoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery1MinSoc { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_minSocBattery1)); set => _minSocBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float SetValueBattery1 { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_setValueBattery1)); set => _setValueBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public SinexcelActiveChargeDischarge ActiveChargeDischarge { get => (SinexcelActiveChargeDischarge)ConvertBitPatternToFloat(_activeChargeDischarge); set => _activeChargeDischarge = (UInt32)value; } public float ActiveChargeDischargePower { get => ConvertBitPatternToFloat(_activeChargeDischargePower) * _factorFromKwtoW; set => _activeChargeDischargePower = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); // we should check this may need to convert from W to KW } // ─────────────────────────────────────────────── // Protection & PV Mode // ─────────────────────────────────────────────── public SinexcelIslandProtection EnableIslandProtection { get => (SinexcelIslandProtection)_enableIslandProtection; set => _enableIslandProtection = (UInt32)value; } public SinexcelPvAccessMode PvAccessMode { get => (SinexcelPvAccessMode)_pvAccessMode; set => _pvAccessMode = (UInt32)value; } // ─────────────────────────────────────────────── // System-Level Parameters // ─────────────────────────────────────────────── public float OutputVoltageAdjustmentFactor { get => BitConverter.Int32BitsToSingle(unchecked((int)_outputVoltageAdjustmentFactor)); set => _outputVoltageAdjustmentFactor = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float SetValueBatteryUndervoltage1 { get => BitConverter.Int32BitsToSingle(unchecked((int)_setValueBatteryUndervoltage1)); set => _setValueBatteryUndervoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float InverterPowerLimit { get => BitConverter.Int32BitsToSingle(unchecked((int)_inverterPowerLimit)); set => _inverterPowerLimit = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } // ─────────────────────────────────────────────── // Battery 2 Parameters // ─────────────────────────────────────────────── public float Battery2Capacity { get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2Capacity)); set => _battery2Capacity = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2MaxChargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((int)_maxChargingCurrentBattery2)); set => _maxChargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2MaxDischargingCurrent { get => BitConverter.Int32BitsToSingle(unchecked((int)_maxDischargingCurrentBattery2)); set => _maxDischargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2RatedVoltage { get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2RatedVoltage)); set => _battery2RatedVoltage = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2MinSoc { get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2MinSoc)); set => _battery2MinSoc = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2OverVoltageSetting { get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2OverVoltageSetting)); set => _battery2OverVoltageSetting = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2UnderVoltageSetpoint { get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2UnderVoltageSetpoint)); set => _battery2UnderVoltageSetpoint = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } // ─────────────────────────────────────────────── // Parallel / System Settings // ─────────────────────────────────────────────── public SinexcelMachineMode MachineMode { get => (SinexcelMachineMode)ConvertBitPatternToFloat(_singleOrParallelMachine); set => _singleOrParallelMachine = (UInt32)value; } public UInt32 NumberOfSystemModules { get => (UInt32)ConvertBitPatternToFloat(_numberOfSystemModules); set => _numberOfSystemModules = value; } public UInt32 ParallelModuleMachineNumber { get => (UInt32)ConvertBitPatternToFloat(_parallelModuleMachineNumber); set => _parallelModuleMachineNumber = value; } public AccreditedCountry AccreditedCountry { get => (AccreditedCountry)ConvertBitPatternToFloat(_accreditedCountries); set => _accreditedCountries = (UInt32)value; } // ─────────────────────────────────────────────── // Control Commands // ─────────────────────────────────────────────── public float PowerOn { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_powerOn)); set => _powerOn = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float PowerOff { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_powerOff)); set => _powerOff = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float FaultClearing { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_faultClearing)); set => _faultClearing = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } // ─────────────────────────────────────────────── // Meter & Battery Control // ─────────────────────────────────────────────── public float MeterReverseManualDetection { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_meterReverseManualDetection)); set => _meterReverseManualDetection = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public SinexcelBatteryRating BatteryVoltageRating { get => (SinexcelBatteryRating)ConvertBitPatternToFloat(_batteryVoltageRating); set => _batteryVoltageRating = (UInt32)value; } public float Battery1Activation { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_battery1Activation)); set => _battery1Activation = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } public float Battery2Activation { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_battery2Activation)); set => _battery2Activation = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } // ─────────────────────────────────────────────── // Electric Meter Operating State // ─────────────────────────────────────────────── public MeterStatus ElectricMeterOperatingState { get => (MeterStatus)BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterOperatingState)); // 0 = Offline, 1 = Online } // ─────────────────────────────────────────────── // Electric Meter Voltages (V) // ─────────────────────────────────────────────── public Voltage ElectricMeterAPhaseVoltage { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseVoltage)); } public Voltage ElectricMeterBPhaseVoltage { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseVoltage)); } public Voltage ElectricMeterCPhaseVoltage { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterCPhaseVoltage)); } // ─────────────────────────────────────────────── // Electric Meter Currents (A) // ─────────────────────────────────────────────── public Current ElectricMeterAPhaseCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseCurrent)); } public Current ElectricMeterBPhaseCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseCurrent)); } public Current ElectricMeterCPhaseCurrent { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterCPhaseCurrent)); } // ─────────────────────────────────────────────── // Electric Meter Active Power (kW) // ─────────────────────────────────────────────── public ActivePower ElectricMeterAPhaseActivePower { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseActivePower)) * _factorFromKwtoW; } public ActivePower ElectricMeterBPhaseActivePower { get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseActivePower)) * _factorFromKwtoW; } public ActivePower 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); float f = BitConverter.ToSingle(intBytes, 0); return f; } private static Single UIntToFloat(UInt32 uintValue) { byte[] uintBytes = BitConverter.GetBytes(uintValue); float f = BitConverter.ToSingle(uintBytes, 0); return f; } public static float ConvertBitPatternToFloat(uint rawValue) { byte[] bytes = BitConverter.GetBytes(rawValue); return BitConverter.ToSingle(bytes, 0); } }