using LFP_Manager.DataStructure; using LFP_Manager.Utils; using System; using System.Windows.Forms; namespace LFP_Manager.Controls { public partial class ucCalibration : DevExpress.XtraEditors.XtraUserControl { #region DELEGATE public delegate void setCalibUpdate(object sender); public delegate void setCalibCommand(int mode, int index, int flag, ref CsDeviceData.DeviceModuleData.DeviceParamData aParm, ref CsDeviceData.DeviceModuleData.DeviceCalibration aCalib); public delegate Int32 getBattData(int item, int cno); #endregion #region ENUMS private enum ControlLevel { User = 0, Technician = 1, Engineer = 2, Master = 3 } private enum CommandMode { SetCapacity = 15, SetChargeMode = 16, SetDateTime = 17, SetAntiTheft = 18, ClearAntiTheft = 19, SetRS485Timeout = 20, SetBalanceVoltage = 21, SetBalanceDiff = 22 } #endregion #region VARIABLES const int CALC_INDEX = 6; CommConfig Config; CsDeviceData.DeviceModuleData ModuleData; CsDeviceData.DeviceModuleData.DeviceCalibration rCalib; CsDeviceData.DeviceModuleData.DeviceCalibration wCalib; CsDeviceData.DeviceModuleData.DeviceParamData rParam; public event setCalibCommand OnCommand = null; int wFlag = 0; int dFlag; int PasswordResult; #endregion #region CONSTRUCTORS // Battery No: // 0: No 1,3,5,7,9,11,13,15 ODD // 1: No 2,4,6,8,10,12,14 Even public ucCalibration() { InitializeComponent(); ComponentLoad(); Config = new CommConfig(); dFlag = 0; } private void ComponentLoad() { CbNewChaMode.Clear(); for (int i = 0; i < csConstData.SystemInfo.CHG_MODE.Length; i++) { CbNewChaMode.Properties.Items.Add(csConstData.SystemInfo.CHG_MODE[i]); } teNewCapacity.KeyPress += TextBox_KeyPress; teNewSoc.KeyPress += TextBox_KeyPress; TeCommTimeoutNew.KeyPress += TextBox_KeyPress; TeChgModeValueNew.KeyPress += TextBox_KeyPress2; } #endregion #region EXT EVENT FUNCTION private void OnCommnadEvent(int mode, int index, int flag, ref CsDeviceData.DeviceModuleData.DeviceParamData aParam, ref CsDeviceData.DeviceModuleData.DeviceCalibration aCalib) { OnCommand?.Invoke(mode, index, flag, ref aParam, ref aCalib); } #endregion #region PUBLIC FUCTIONS public void UpdateConfig(CommConfig aConfig) { Config = aConfig; } public void UpdateData(CsDeviceData.DeviceModuleData mData, CsDeviceData.DeviceModuleData.DeviceCalibration aCalib) { ModuleData = mData; rCalib = aCalib; DisplayCalib(); UpdateNewCalib(); } private void UpdateNewCalib() { if (ModuleData != null) { if (wFlag == 0) { teNewCapacity.Text = teCurrCapacity.Text; teNewSoc.Text = teCurrSoc.Text; wFlag = 1; } } } #endregion #region DISPLAY DATA private void DisplayCalib() { if (ModuleData != null) { teCurrCapacity.Text = string.Format("{0}", ModuleData.ValueData.designedCapacity / 10); teCurrSoc.Text = string.Format("{0}", ModuleData.ValueData.SOC / 10); switch (ModuleData.CalibrationData.ChaMode.Mode) { case 0: TeChaMode.Text = csConstData.SystemInfo.CHG_MODE[0]; break; case 1: TeChaMode.Text = csConstData.SystemInfo.CHG_MODE[1]; break; case 2: TeChaMode.Text = csConstData.SystemInfo.CHG_MODE[2]; break; case 4: TeChaMode.Text = csConstData.SystemInfo.CHG_MODE[3]; break; case 8: TeChaMode.Text = csConstData.SystemInfo.CHG_MODE[4]; break; default: TeChaMode.Text = string.Format("UNKNOWN({0})", ModuleData.CalibrationData.ChaMode.Mode); break; } TeChgModeValueCurr.Text = string.Format("{0:0.00}", Convert.ToDouble(ModuleData.CalibrationData.ChaMode.Value) / 100); TeCurrDateTime.Text = ModuleData.BmsDateTime.DateTimeStr; // Anti-Theft Data Display if (ModuleData.CalibrationData.AntiTheft.GyroScope == 0) { TeAntiTheftGyroCurr.Text = "DISABLE"; } else { TeAntiTheftGyroCurr.Text = "ENABLE"; } TeSensitive.Text = string.Format("{0}", ModuleData.CalibrationData.AntiTheft.GyroScope); // Anti-Theft - RS-485 Comm. Timeout TeCommTimeout.Text = string.Format("{0}", ModuleData.CalibrationData.AntiTheft.Comm); if (dFlag == 0) { CbNewChaMode.SelectedIndex = 1; switch (ModuleData.CalibrationData.ChaMode.Mode) { case 0: CbNewChaMode.SelectedIndex = 0; break; case 1: CbNewChaMode.SelectedIndex = 1; break; case 2: CbNewChaMode.SelectedIndex = 2; break; case 4: CbNewChaMode.SelectedIndex = 3; break; case 8: CbNewChaMode.SelectedIndex = 4; break; default: CbNewChaMode.Text = string.Format("UNKNOWN({0})", ModuleData.CalibrationData.ChaMode.Mode); break; } TeChgModeValueNew.Text = TeChgModeValueCurr.Text; dFlag = 1; } } } #endregion #region BUTTON EVENT private void TextBox_KeyPress(object sender, KeyPressEventArgs e) { csUtils.TypingOnlyNumber(sender, e, false, false); } private void TextBox_KeyPress2(object sender, KeyPressEventArgs e) { csUtils.TypingOnlyNumber(sender, e, true, false); } private void btnCapacitySet_Click(object sender, EventArgs e) { try { if (!ValidateNumericInput(teNewCapacity.Text, "Capacity") || !ValidateNumericInput(teNewSoc.Text, "SOC")) { return; } wCalib = rCalib.DeepCopy(); wCalib.CapCalib.DesignCapacity = Convert.ToInt32(teNewCapacity.Text) * 10; wCalib.CapCalib.SocValue = Convert.ToInt32(teNewSoc.Text); OnCommnadEvent((int)CommandMode.SetCapacity, CALC_INDEX, 1, ref rParam, ref wCalib); } catch (Exception ex) { ShowError($"Failed to set capacity: {ex.Message}"); } } private void BtnChaModeSet_Click(object sender, EventArgs e) { try { if (string.IsNullOrEmpty(CbNewChaMode.Text)) { ShowError("Please select a charge mode"); return; } if (CbNewChaMode.SelectedIndex > 1 && !ValidateNumericInput(TeChgModeValueNew.Text, "Charge Mode Value")) { return; } wCalib = rCalib.DeepCopy(); wCalib.ChaMode.Mode = CbNewChaMode.SelectedIndex; wCalib.ChaMode.Value = (int)(Convert.ToDouble(TeChgModeValueNew.Text) * 100); OnCommnadEvent((int)CommandMode.SetChargeMode, CALC_INDEX, 1, ref rParam, ref wCalib); } catch (Exception ex) { ShowError($"Failed to set charge mode: {ex.Message}"); } } private void BtnBmsDateTimeSet_Click(object sender, EventArgs e) { try { if (string.IsNullOrEmpty(TeNewDateTime.Text)) { ShowError("Please enter a date/time value"); return; } DateTime dateTime = Convert.ToDateTime(TeNewDateTime.Text); int iDateTime = CalculateDateTimeValue(dateTime); wCalib = rCalib.DeepCopy(); wCalib.BmsDateTime.sValue[0] = (short)(iDateTime >> 16); wCalib.BmsDateTime.sValue[1] = (short)(iDateTime >> 0); OnCommnadEvent((int)CommandMode.SetDateTime, CALC_INDEX, 1, ref rParam, ref wCalib); } catch (Exception ex) { ShowError($"Failed to set date/time: {ex.Message}"); } } private int CalculateDateTimeValue(DateTime dateTime) { return ((dateTime.Year - 2000) << 26) | (dateTime.Month << 22) | (dateTime.Day << 17) | (dateTime.Hour << 12) | (dateTime.Minute << 6) | (dateTime.Second << 0); } private void BtnGetCurrTime_Click(object sender, EventArgs e) { TeNewDateTime.Text = string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now); } private void BtnClearAntiTheftProtect_Click(object sender, EventArgs e) { wCalib = rCalib.DeepCopy(); wCalib.AntiTheft.GyroScope = Config.GyroSensitive; OnCommnadEvent(19, CALC_INDEX, 1, ref rParam, ref wCalib); } private void PassWordResultProc(int result) { PasswordResult = result; } private void BtnAntiTheftEnable_Click(object sender, EventArgs e) { wCalib = rCalib.DeepCopy(); wCalib.AntiTheft.GyroScope = Config.GyroSensitive; OnCommnadEvent(18, CALC_INDEX, 1, ref rParam, ref wCalib); } private void BtnAntiTheftDisable_Click(object sender, EventArgs e) { wCalib = rCalib.DeepCopy(); wCalib.AntiTheft.GyroScope = 0; OnCommnadEvent(18, CALC_INDEX, 1, ref rParam, ref wCalib); } private void BtnRS485TimeoutSet_Click(object sender, EventArgs e) { string stTimeout = TeCommTimeoutNew.Text; int Timeout = 0; try { Timeout = Convert.ToInt32(stTimeout); } catch (Exception) { MessageBox.Show("Timeout data Format Error", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } wCalib = rCalib.DeepCopy(); wCalib.AntiTheft.Comm = Timeout; OnCommnadEvent(20, CALC_INDEX, 1, ref rParam, ref wCalib); } #endregion #region COMPONENT EVENT private void CbNewChaMode_SelectedIndexChanged(object sender, EventArgs e) { switch (CbNewChaMode.SelectedIndex) { case 0: TeChgModeValueNew.Enabled = false; break; case 1: TeChgModeValueNew.Enabled = false; break; case 2: TeChgModeValueNew.Enabled = true; break; case 3: TeChgModeValueNew.Enabled = true; break; case 4: TeChgModeValueNew.Enabled = true; break; default: TeChgModeValueNew.Enabled = false; break; } } #endregion #region FORM EVENT private void ucCalibration_Load(object sender, EventArgs e) { CalibConfig_ReLoad(); } private void CalibConfig_ReLoad() { var level = (ControlLevel)Config.ControlLevel; btnCapacitySet.Enabled = level == ControlLevel.Master; BtnChaModeSet.Enabled = level >= ControlLevel.Engineer; BtnBmsDateTimeSet.Enabled = level >= ControlLevel.Engineer; BtnClearAntiTheftProtect.Enabled = level >= ControlLevel.Technician; BtnAntiTheftEnable.Enabled = level >= ControlLevel.Engineer; BtnAntiTheftDisable.Enabled = level >= ControlLevel.Engineer; BtnRS485TimeoutSet.Enabled = level >= ControlLevel.Technician; } #endregion #region VALIDATION METHODS private bool ValidateNumericInput(string input, string fieldName) { if (string.IsNullOrEmpty(input)) { ShowError($"Please enter a value for {fieldName}"); return false; } if (!int.TryParse(input, out _)) { ShowError($"Invalid numeric value for {fieldName}"); return false; } return true; } private void ShowError(string message) { MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } #endregion } }