468 lines
22 KiB
C#
468 lines
22 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using BMS_D1000H.BMSConstData;
|
|
using BMS_D1000H.DataStructs;
|
|
using BMS_D1000H.Utils.Functions;
|
|
|
|
namespace BMS_D1000H
|
|
{
|
|
public partial class fmParamSetCmd : Form
|
|
{
|
|
public int SetID = 0;
|
|
short Reg_Addr;
|
|
short Reg_Count;
|
|
short[] Reg_Data;
|
|
|
|
DeviceParam disTrayParam;
|
|
|
|
public fmParamSetCmd()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
private void Control_ReLoad_A()
|
|
{
|
|
this.SuspendLayout();
|
|
this.Controls.Clear();
|
|
|
|
this.Controls.Add(this.lbSetResult);
|
|
this.Controls.Add(this.tbRecovery);
|
|
this.Controls.Add(this.tbWarning);
|
|
this.Controls.Add(this.lbRecovery);
|
|
this.Controls.Add(this.lbWarning);
|
|
this.Controls.Add(this.lbProtection);
|
|
this.Controls.Add(this.smartLabel4);
|
|
this.Controls.Add(this.smartLabel3);
|
|
this.Controls.Add(this.smartLabel2);
|
|
this.Controls.Add(this.kbdValue);
|
|
this.Controls.Add(this.tbProtection);
|
|
this.Controls.Add(this.btnOk);
|
|
this.Controls.Add(this.btnCancel);
|
|
this.Controls.Add(this.lbConfigName);
|
|
this.Controls.Add(this.sfmParamSetCmd);
|
|
|
|
this.ResumeLayout(false);
|
|
}
|
|
|
|
private void Control_ReLoad_B()
|
|
{
|
|
this.SuspendLayout();
|
|
this.Controls.Clear();
|
|
|
|
this.Controls.Add(this.lbSetResult);
|
|
this.Controls.Add(this.tbRecovery);
|
|
this.Controls.Add(this.tbWarning);
|
|
this.Controls.Add(this.lbRecovery);
|
|
this.Controls.Add(this.lbWarning);
|
|
//this.Controls.Add(this.lbProtection);
|
|
this.Controls.Add(this.smartLabel4);
|
|
this.Controls.Add(this.smartLabel3);
|
|
this.Controls.Add(this.smartLabel2);
|
|
this.Controls.Add(this.kbdValue);
|
|
//this.Controls.Add(this.tbProtection);
|
|
this.Controls.Add(this.btnOk);
|
|
this.Controls.Add(this.btnCancel);
|
|
this.Controls.Add(this.lbConfigName);
|
|
this.Controls.Add(this.sfmParamSetCmd);
|
|
|
|
this.ResumeLayout(false);
|
|
}
|
|
|
|
private void tbProtection_GotFocus(object sender, EventArgs e)
|
|
{
|
|
kbdValue.Location = new System.Drawing.Point(210, 172);
|
|
kbdValue.TargetInputObject = tbProtection;
|
|
kbdValue.Show();
|
|
}
|
|
|
|
private void tbWarning_GotFocus(object sender, EventArgs e)
|
|
{
|
|
kbdValue.Location = new System.Drawing.Point(352, 172);
|
|
kbdValue.TargetInputObject = tbWarning;
|
|
kbdValue.Show();
|
|
}
|
|
|
|
private void tbRecovery_GotFocus(object sender, EventArgs e)
|
|
{
|
|
kbdValue.Location = new System.Drawing.Point(499, 172);
|
|
kbdValue.TargetInputObject = tbRecovery;
|
|
kbdValue.Show();
|
|
}
|
|
|
|
private void btnCancel_Click(object sender, EventArgs e)
|
|
{
|
|
((fmBMSMain)(Owner)).ScreenSaverTimeReset();
|
|
((fmBMSMain)(Owner)).sfmMain.Show(4);
|
|
}
|
|
|
|
private void fmParamSetCmd_Activated(object sender, EventArgs e)
|
|
{
|
|
lbConfigName.Text = SetParamter.Name[SetID - 1];
|
|
DisplayParameter(true);
|
|
|
|
tbProtection.Text = lbProtection.Text;
|
|
tbWarning.Text = lbWarning.Text;
|
|
tbRecovery.Text = lbRecovery.Text;
|
|
|
|
switch (SetID)
|
|
{
|
|
case 3:
|
|
case 4:
|
|
case 6:
|
|
case 8:
|
|
case 9:
|
|
Control_ReLoad_B();
|
|
kbdValue.Location = new System.Drawing.Point(352, 172);
|
|
kbdValue.TargetInputObject = tbWarning;
|
|
break;
|
|
default:
|
|
Control_ReLoad_A();
|
|
kbdValue.Location = new System.Drawing.Point(210, 172);
|
|
kbdValue.TargetInputObject = tbProtection;
|
|
break;
|
|
}
|
|
kbdValue.Show();
|
|
}
|
|
|
|
private void DisplayParameter(bool p)
|
|
{
|
|
int aParam;
|
|
DeviceDataSystem aBMSData;
|
|
|
|
aBMSData = ((fmBMSMain)(Owner)).GetBmsSystemData();
|
|
|
|
switch (SetID)
|
|
{
|
|
case 1: // SOV
|
|
// SOV Parameter display
|
|
if (p || (disTrayParam.voltage.SOV_Threshold != aBMSData.param.voltage.SOV_Threshold))
|
|
{
|
|
aParam = aBMSData.param.voltage.SOV_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0.00}", Convert.ToDouble(aParam) / 100);
|
|
disTrayParam.voltage.SOV_Threshold = aBMSData.param.voltage.SOV_Threshold;
|
|
}
|
|
if (p || (disTrayParam.voltage.SOV_Warning != aBMSData.param.voltage.SOV_Warning))
|
|
{
|
|
aParam = aBMSData.param.voltage.SOV_Warning;
|
|
lbWarning.Text = String.Format("{0:#0.00}", Convert.ToDouble(aParam) / 100);
|
|
disTrayParam.voltage.SOV_Warning = aBMSData.param.voltage.SOV_Warning;
|
|
}
|
|
if (p || (disTrayParam.voltage.SOV_Recovery != aBMSData.param.voltage.SOV_Recovery))
|
|
{
|
|
aParam = aBMSData.param.voltage.SOV_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0.00}", Convert.ToDouble(aParam) / 100);
|
|
disTrayParam.voltage.SOV_Recovery = aBMSData.param.voltage.SOV_Recovery;
|
|
}
|
|
break;
|
|
case 2: // COV
|
|
// COV Parameter display
|
|
if (p || (disTrayParam.voltage.COV_Threshold != aBMSData.param.voltage.COV_Threshold))
|
|
{
|
|
aParam = aBMSData.param.voltage.COV_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0.000}", Convert.ToDouble(aParam) / 1000);
|
|
disTrayParam.voltage.COV_Threshold = aBMSData.param.voltage.COV_Threshold;
|
|
}
|
|
if (p || (disTrayParam.voltage.COV_Warning != aBMSData.param.voltage.COV_Warning))
|
|
{
|
|
aParam = aBMSData.param.voltage.COV_Warning;
|
|
lbWarning.Text = String.Format("{0:#0.000}", Convert.ToDouble(aParam) / 1000);
|
|
disTrayParam.voltage.COV_Warning = aBMSData.param.voltage.COV_Warning;
|
|
}
|
|
if (p || (disTrayParam.voltage.COV_Recovery != aBMSData.param.voltage.COV_Recovery))
|
|
{
|
|
aParam = aBMSData.param.voltage.COV_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0.000}", Convert.ToDouble(aParam) / 1000);
|
|
disTrayParam.voltage.COV_Recovery = aBMSData.param.voltage.COV_Recovery;
|
|
}
|
|
break;
|
|
case 3: // SUV
|
|
//SUV Parameter display
|
|
if (p || (disTrayParam.voltage.SUV_Threshold != aBMSData.param.voltage.SUV_Threshold))
|
|
{
|
|
aParam = aBMSData.param.voltage.SUV_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0.00} ", Convert.ToDouble(aParam) / 100);
|
|
disTrayParam.voltage.SUV_Threshold = aBMSData.param.voltage.SUV_Threshold;
|
|
}
|
|
if (p || (disTrayParam.voltage.SUV_Warning != aBMSData.param.voltage.SUV_Warning))
|
|
{
|
|
aParam = aBMSData.param.voltage.SUV_Warning;
|
|
lbWarning.Text = String.Format("{0:#0.00}", Convert.ToDouble(aParam) / 100);
|
|
disTrayParam.voltage.SUV_Warning = aBMSData.param.voltage.SUV_Warning;
|
|
}
|
|
if (p || (disTrayParam.voltage.SUV_Recovery != aBMSData.param.voltage.SUV_Recovery))
|
|
{
|
|
aParam = aBMSData.param.voltage.SUV_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0.00}", Convert.ToDouble(aParam) / 100);
|
|
disTrayParam.voltage.SUV_Recovery = aBMSData.param.voltage.SUV_Recovery;
|
|
}
|
|
break;
|
|
case 4: // CUV
|
|
// CUV Parameter display
|
|
if (p || (disTrayParam.voltage.CUV_Threshold != aBMSData.param.voltage.CUV_Threshold))
|
|
{
|
|
aParam = aBMSData.param.voltage.CUV_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0.000} ", Convert.ToDouble(aParam) / 1000);
|
|
disTrayParam.voltage.CUV_Threshold = aBMSData.param.voltage.CUV_Threshold;
|
|
}
|
|
if (p || (disTrayParam.voltage.CUV_Warning != aBMSData.param.voltage.CUV_Warning))
|
|
{
|
|
aParam = aBMSData.param.voltage.CUV_Warning;
|
|
lbWarning.Text = String.Format("{0:#0.000}", Convert.ToDouble(aParam) / 1000);
|
|
disTrayParam.voltage.CUV_Warning = aBMSData.param.voltage.CUV_Warning;
|
|
}
|
|
if (p || (disTrayParam.voltage.CUV_Recovery != aBMSData.param.voltage.CUV_Recovery))
|
|
{
|
|
aParam = aBMSData.param.voltage.CUV_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0.000}", Convert.ToDouble(aParam) / 1000);
|
|
disTrayParam.voltage.CUV_Recovery = aBMSData.param.voltage.CUV_Recovery;
|
|
}
|
|
break;
|
|
case 5: // OCC
|
|
// OC Charge Parameter display
|
|
if (p || (disTrayParam.current.OC_Chg_Threshold != aBMSData.param.current.OC_Chg_Threshold))
|
|
{
|
|
aParam = aBMSData.param.current.OC_Chg_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.current.OC_Chg_Threshold = aBMSData.param.current.OC_Chg_Threshold;
|
|
}
|
|
if (p || (disTrayParam.current.OC_Chg_Warning != aBMSData.param.current.OC_Chg_Warning))
|
|
{
|
|
aParam = aBMSData.param.current.OC_Chg_Warning;
|
|
lbWarning.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.current.OC_Chg_Warning = aBMSData.param.current.OC_Chg_Warning;
|
|
}
|
|
if (p || (disTrayParam.current.OC_Chg_Recovery != aBMSData.param.current.OC_Chg_Recovery))
|
|
{
|
|
aParam = aBMSData.param.current.OC_Chg_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.current.OC_Chg_Recovery = aBMSData.param.current.OC_Chg_Recovery;
|
|
}
|
|
break;
|
|
case 6: // OCD
|
|
// OC Discharge Parameter display
|
|
if (p || (disTrayParam.current.OC_Dsg_Threshold != aBMSData.param.current.OC_Dsg_Threshold))
|
|
{
|
|
aParam = aBMSData.param.current.OC_Dsg_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0} ", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.current.OC_Dsg_Threshold = aBMSData.param.current.OC_Dsg_Threshold;
|
|
}
|
|
if (p || (disTrayParam.current.OC_Dsg_Warning != aBMSData.param.current.OC_Dsg_Warning))
|
|
{
|
|
aParam = aBMSData.param.current.OC_Dsg_Warning;
|
|
lbWarning.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.current.OC_Dsg_Warning = aBMSData.param.current.OC_Dsg_Warning;
|
|
}
|
|
if (p || (disTrayParam.current.OC_Dsg_Recovery != aBMSData.param.current.OC_Dsg_Recovery))
|
|
{
|
|
aParam = aBMSData.param.current.OC_Dsg_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.current.OC_Dsg_Recovery = aBMSData.param.current.OC_Dsg_Recovery;
|
|
}
|
|
break;
|
|
case 7: // OTC
|
|
// OT Charge Parameter display
|
|
if (p || (disTrayParam.temperature.OT_Chg_Threshold != aBMSData.param.temperature.OT_Chg_Threshold))
|
|
{
|
|
aParam = aBMSData.param.temperature.OT_Chg_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.temperature.OT_Chg_Threshold = aBMSData.param.temperature.OT_Chg_Threshold;
|
|
}
|
|
if (p || (disTrayParam.temperature.OT_Chg_Warning != aBMSData.param.temperature.OT_Chg_Warning))
|
|
{
|
|
aParam = aBMSData.param.temperature.OT_Chg_Warning;
|
|
lbWarning.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.temperature.OT_Chg_Warning = aBMSData.param.temperature.OT_Chg_Warning;
|
|
}
|
|
if (p || (disTrayParam.temperature.OT_Chg_Recovery != aBMSData.param.temperature.OT_Chg_Recovery))
|
|
{
|
|
aParam = aBMSData.param.temperature.OT_Chg_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.temperature.OT_Chg_Recovery = aBMSData.param.temperature.OT_Chg_Recovery;
|
|
}
|
|
break;
|
|
case 8: // OTD
|
|
// OT Discharge Parameter display
|
|
if (p || (disTrayParam.temperature.OT_Dsg_Threshold != aBMSData.param.temperature.OT_Dsg_Threshold))
|
|
{
|
|
aParam = aBMSData.param.temperature.OT_Dsg_Threshold;
|
|
lbProtection.Text = String.Format("{0:#0} ", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.temperature.OT_Dsg_Threshold = aBMSData.param.temperature.OT_Dsg_Threshold;
|
|
}
|
|
if (p || (disTrayParam.temperature.OT_Dsg_Warning != aBMSData.param.temperature.OT_Dsg_Warning))
|
|
{
|
|
aParam = aBMSData.param.temperature.OT_Dsg_Warning;
|
|
lbWarning.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.temperature.OT_Dsg_Warning = aBMSData.param.temperature.OT_Dsg_Warning;
|
|
}
|
|
if (p || (disTrayParam.temperature.OT_Dsg_Recovery != aBMSData.param.temperature.OT_Dsg_Recovery))
|
|
{
|
|
aParam = aBMSData.param.temperature.OT_Dsg_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.temperature.OT_Dsg_Recovery = aBMSData.param.temperature.OT_Dsg_Recovery;
|
|
}
|
|
break;
|
|
case 9: // SOC
|
|
// SOC Parameter display
|
|
if (p || (disTrayParam.soc.Low_SOC_Warning != aBMSData.param.soc.Low_SOC_Warning))
|
|
{
|
|
aParam = aBMSData.param.soc.Low_SOC_Warning;
|
|
lbWarning.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.soc.Low_SOC_Warning = aBMSData.param.soc.Low_SOC_Warning;
|
|
}
|
|
if (p || (disTrayParam.soc.Low_SOC_Recovery != aBMSData.param.soc.Low_SOC_Recovery))
|
|
{
|
|
aParam = aBMSData.param.soc.Low_SOC_Recovery;
|
|
lbRecovery.Text = String.Format("{0:#0}", Convert.ToDouble(aParam) / 1);
|
|
disTrayParam.soc.Low_SOC_Recovery = aBMSData.param.soc.Low_SOC_Recovery;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void tmrDisplay_Tick(object sender, EventArgs e)
|
|
{
|
|
DisplayParameter(false);
|
|
}
|
|
|
|
private void fmParamSetCmd_Load(object sender, EventArgs e)
|
|
{
|
|
tmrDisplay.Start();
|
|
}
|
|
|
|
private void btnOk_Click(object sender, EventArgs e)
|
|
{
|
|
bool aa = true;
|
|
bool flag = false;
|
|
|
|
((fmBMSMain)(Owner)).ScreenSaverTimeReset();
|
|
|
|
if ((tbProtection.Text == "") ||
|
|
(tbWarning.Text == "") ||
|
|
(tbRecovery.Text == ""))
|
|
{
|
|
lbSetResult.Text = "Cannot empty parameter";
|
|
return;
|
|
}
|
|
|
|
Reg_Addr = Convert.ToInt16(60 + ((SetID - 1) * 3));
|
|
Reg_Count = 3;
|
|
Reg_Data = new short[Reg_Count];
|
|
|
|
switch (SetID)
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1: // System Over Voltage 69
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 100);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 100);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 100);
|
|
Reg_Addr = Convert.ToInt16(69);
|
|
aa = true;
|
|
break;
|
|
case 2: // Cell Over Voltage 66
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 1000);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 1000);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 1000);
|
|
Reg_Addr = Convert.ToInt16(66);
|
|
aa = true;
|
|
break;
|
|
case 3: // System Under Voltage
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 100);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 100);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 100);
|
|
Reg_Addr = Convert.ToInt16(63);
|
|
aa = false;
|
|
break;
|
|
case 4: // Cell Under Voltage 60
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 1000);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 1000);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 1000);
|
|
Reg_Addr = Convert.ToInt16(60);
|
|
aa = false;
|
|
break;
|
|
case 5: // Charge Over Current 72
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 1);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 1);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 1);
|
|
Reg_Addr = Convert.ToInt16(72);
|
|
aa = true;
|
|
break;
|
|
case 6: // Discharge Over Current 76
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 1);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 1);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 1);
|
|
Reg_Addr = Convert.ToInt16(72);
|
|
aa = true;
|
|
break;
|
|
case 7: // Charge High Temperature 80
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 10);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 10);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 10);
|
|
Reg_Addr = Convert.ToInt16(80);
|
|
aa = true;
|
|
break;
|
|
case 8: // Discharge High Temperature 84
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbProtection.Text) * 10);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbWarning.Text) * 10);
|
|
Reg_Data[2] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 10);
|
|
Reg_Addr = Convert.ToInt16(84);
|
|
aa = true;
|
|
break;
|
|
case 9: // Low Capacity 88
|
|
Reg_Data[0] = Convert.ToInt16(double.Parse(tbWarning.Text) * 1);
|
|
Reg_Data[1] = Convert.ToInt16(double.Parse(tbRecovery.Text) * 1);
|
|
Reg_Addr = Convert.ToInt16(88);
|
|
Reg_Count = 2;
|
|
aa = false;
|
|
break;
|
|
}
|
|
|
|
if (aa)
|
|
{
|
|
// Forward
|
|
if (Reg_Count == 2)
|
|
{
|
|
if (Reg_Data[0] > Reg_Data[1])
|
|
flag = true;
|
|
}
|
|
else if (Reg_Count == 3)
|
|
{
|
|
if ((Reg_Data[0] > Reg_Data[1])&&(Reg_Data[1] > Reg_Data[2]))
|
|
flag = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Backward
|
|
if (Reg_Count == 2)
|
|
{
|
|
if (Reg_Data[0] < Reg_Data[1])
|
|
flag = true;
|
|
}
|
|
else if (Reg_Count == 3)
|
|
{
|
|
if ((Reg_Data[0] < Reg_Data[1]) && (Reg_Data[1] < Reg_Data[2]))
|
|
flag = true;
|
|
}
|
|
}
|
|
|
|
if ((tbProtection.Text == "") ||
|
|
(tbWarning.Text == "") ||
|
|
(tbRecovery.Text == ""))
|
|
{
|
|
lbSetResult.Text = "Cannot empty parameter";
|
|
return;
|
|
}
|
|
|
|
((fmBMSMain)(Owner)).SetModBusWriteCmd(1, Reg_Addr, Reg_Count, Reg_Data, 1);
|
|
|
|
((fmBMSMain)(Owner)).ChangeScreen(0, 0, ScreenID.PARAM_SET_SCREEN_ID);
|
|
}
|
|
}
|
|
} |