The following sections introduce the method of implementing the vending machine interface of C#. The code is written in very detailed. If you don’t understand, please refer to the comments.
MachineJP class:
Part 1: Serial port initialization, serial port data reading and writing
using System; using ; using ; using ; using ; using ; using ; using ; using ; using ; namespace MachineJPDll { /// <summary> /// Vending machine interface (interface) /// </summary> public partial class MachineJP { #region variable /// <summary> /// Serial port resources /// </summary> private SerialPort m_SerialPort = null; /// <summary> /// List of commands to be sent to the serial port /// </summary> private List<Cmd> m_CommandList = new List<Cmd>(); /// <summary> /// List of messages sent by the PC side of ACK_RPT or NAK_RPT to the VMC side /// </summary> private List<MT> m_WaitResultMTList = new List<MT>(); /// <summary> /// Collection of data received from the serial port (data has been verified) /// </summary> private ReceiveDataCollection m_ReceiveDataCollection = new ReceiveDataCollection(); #endregion #region constructor and destructor /// <summary> /// Vending machine interface (interface) /// </summary> public MachineJP() { } ~MachineJP() { if (m_SerialPort != null) { m_SerialPort.Close(); m_SerialPort.Dispose(); m_SerialPort = null; } } #endregion #region Read serial port data /// <summary> /// Read serial port data /// </summary> /// <returns>Data read from serial port</returns> private byte[] ReadPort() { //Read serial port data DateTime dt = ; while (m_SerialPort.BytesToRead < 2) { (1); if ((dt).TotalMilliseconds > 1500) //time out { return new byte[0]; } } List<byte> recList = new List<byte>(); byte[] recData = new byte[m_SerialPort.BytesToRead]; m_SerialPort.Read(recData, 0, ); (recData); int length = recData[1] + 2; //Total length of packet data while ( < length) { if (m_SerialPort.BytesToRead > 0) { recData = new byte[m_SerialPort.BytesToRead]; m_SerialPort.Read(recData, 0, ); (recData); } (1); } return (); } #endregion #region Send data to the serial port /// <summary> /// Send data to the serial port /// </summary> /// <param name="cmd">Command to be sent</param> /// <param name="SN">Serial number</param> private void WritePort(Cmd cmd, byte SN) { //Send data List<byte> sendData = ; sendData[1] = (byte); sendData[2] = SN; byte[] checkCode = (sendData, ); (checkCode); if ( != null) { m_WaitResultMTList.Add(); } m_SerialPort.Write((), 0, ); (, true, ()); } #endregion #region Send ACK message /// <summary> /// Send ACK message /// </summary> /// <param name="SN">Serial number</param> private void SendACK(byte SN) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x40, 0x80 }; WritePort(new Cmd(sendData), SN); } #endregion #region Init Init /// <summary> /// Initialization /// </summary> /// <param name="com">Serial port number (example: COM1)</param> public void Init(string com) { if (m_SerialPort == null) { m_SerialPort = new SerialPort(com, 9600, , 8, ); m_SerialPort.ReadBufferSize = 1024; m_SerialPort.WriteBufferSize = 1024; m_SerialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived); } if (!m_SerialPort.IsOpen) { m_SerialPort.Open(); } GET_SETUP(); CONTROL_IND(0x13, new byte[] { 0x00 }); //Initialization completion flag GET_STATUS(); SetDecimalPlaces(2); //Set the number of decimal places } #endregion #region Close Connection /// <summary> /// Close the connection /// </summary> public void Close() { m_SerialPort.Close(); } #endregion #region Receive serial port data /// <summary> /// Receive serial port data /// </summary> /// <param name="type">Message Type</param> /// <param name="subtype">Message subtype</param> public byte[] Receive(byte type, byte subtype) { return m_ReceiveDataCollection.Get(type, subtype); } /// <summary> /// Receive serial port data /// </summary> /// <param name="type">Message Type</param> /// <param name="subtype">Message subtype</param> public byte[] WaitReceive(byte type, byte subtype) { DateTime time = ; while (true) { byte[] receiveData = m_ReceiveDataCollection.Get(type, subtype); if (receiveData != null) return receiveData; if ((time).TotalMinutes > 3) return null; (50); } } /// <summary> /// Receive serial port data /// </summary> /// <param name="type">Message Type</param> public byte[] WaitReceive(byte type) { DateTime time = ; while (true) { byte[] receiveData = m_ReceiveDataCollection.Get(type); if (receiveData != null) return receiveData; if ((time).TotalMinutes > 3) return null; (50); } } #endregion #region Determine whether the message is sent successfully /// <summary> /// Determine whether the message is sent successfully /// </summary> public bool SendSuccess(byte type, byte subtype) { DateTime time = ; while (true) { if ((time).TotalMinutes > 3) { return false; } byte[] ack = m_ReceiveDataCollection.Get(type, subtype); byte[] nak = m_ReceiveDataCollection.Get(type, subtype); if (ack != null) return true; if (nak != null) return false; (1); } } #endregion } }
Part 2: Receive serial port data and respond to the freighter and send data to the freighter.
using System; using ; using ; using ; using ; using ; using ; /* * VMC-> PC data reception, freighter event distribution */ namespace MachineJPDll { partial class MachineJP { #region serialPort_DataReceived /// <summary> /// Method of receiving data events /// </summary> public void serialPort_DataReceived(object obj, SerialDataReceivedEventArgs args) { byte[] receiveData = ReadPort(); if ((receiveData)) //Only process the correct data, discard the incorrect data and not process it { (, false, receiveData); byte SN = (receiveData); MT mt = new MT(receiveData); #region polling (POLL) if ( == 0x03) { if (m_CommandList.Count > 0) { WritePort(m_CommandList[0], SN); m_CommandList.RemoveAt(0); } else { //Send ACK message SendACK(SN); } } #endregion #region Send ACK message if ((receiveData)) { SendACK(SN); //Send ACK message } #endregion #region VMC system parameters if ( == 0x05) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region ACK_RPT or NAK_RPT if ( == 0x01 //ACK_RPT || == 0x02) //NAK_RPT { if (m_WaitResultMTList.Count > 0) { m_ReceiveDataCollection.Add(m_WaitResultMTList[0].Type, m_WaitResultMTList[0].Subtype, receiveData); m_WaitResultMTList.RemoveAt(0); } } #endregion #region INFO_RPT Data Report if ( == 0x11) { #region banknote information if ( == 16) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region Coin Message if ( == 17) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region User coin balance if ( == 3) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion } #endregion #region VENDOUT_RPT Shipping Report if ( == 0x08) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region STATUS_RPT VMC whole machine status report if ( == 0x0D) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region SALEPRICE_IND Set the current product price if ( == 0x8E) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region PAYIN_RPT VMC sends cash coin report to PC if ( == 0x06) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region PAYOUT_RPT Coin Output Report if ( == 0x07) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region COST_RPT VMC Deduction Report if ( == 0x10) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region ACTION_RPT Vending Machine Behavior Report if ( == 0x0B) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion #region HUODAO_RPT VMC cargo lane report if ( == 0x0E) { m_ReceiveDataCollection.Add(, , receiveData); } #endregion } else //The received data has not been verified { (, false, "Data exception", receiveData); } } #endregion } }
Part 3: Freighter status, coin input, shipment and other interfaces
using System; using ; using ; using ; using ; using ; using ; using ; /* * PC->VMC data sending (not directly sending, just adding it to the sending list) */ namespace MachineJPDll { partial class MachineJP { #region GET_SETUP /// <summary> /// PC notifies VMC to send VMC_SETUP /// </summary> public VmcSetup GET_SETUP() { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x40, 0x90 }; m_CommandList.Add(new Cmd(sendData)); byte[] receiveData = WaitReceive(0x05); if (receiveData != null) { return new VmcSetup(receiveData); } return null; } #endregion #region CONTROL_IND PC controls the vending machine to complete the corresponding actions /// <summary> /// PC control VMC /// </summary> public bool CONTROL_IND(byte subtype, byte[] value) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x85 }; (subtype); if (value != null && > 0) { (value); } m_CommandList.Add(new Cmd(sendData, new MT(sendData))); return SendSuccess(0x85, subtype); } #endregion #region Set the number of decimal places /// <summary> /// Set the number of decimal points /// Used to notify VMC of the VMC, the ratio coefficient relationship between the amount data of both parties, and the PC will give each time it is started. /// VMC issues a message of type=18. VMC needs to save the data permanently until it is then passed by the PC. /// Updated. /// Value range: 0, 1, 2 respectively representing units of numerals, angles, and divisions respectively /// </summary> public bool SetDecimalPlaces(int data) { return CONTROL_IND(18, new byte[] { (byte)data }); } #endregion #region GET_STATUS PC notifies VMC to send STATUS_RPT /// <summary> /// PC notifies VMC to send STATUS_RPT /// </summary> public StatusRpt GET_STATUS() { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x40, 0x86 }; m_CommandList.Add(new Cmd(sendData)); byte[] receiveData = WaitReceive(0x0D); if (receiveData != null) { return new StatusRpt(receiveData); } return null; } #endregion #region GET_INFO PC notifies VMC to send INFO_RPT /// <summary> /// PC notifies VMC to send INFO_RPT /// </summary> public byte[] GET_INFO(byte subtype) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x40, 0x8C }; (subtype); m_CommandList.Add(new Cmd(sendData)); return WaitReceive(0x11); } #endregion #region VENDOUT_IND Shipping /// <summary> /// PC shipment instructions /// </summary> /// <param name="device">The box number of the vending machine, for example, cabinet 1 is 0x01, and so on</param> /// <param name="method">method =1: VMC indicates shipment through the product ID. If the product ID does not exist, reply NAK_RPT method =2: VMC indicates shipment through the cargo lane ID. If the cargo lane ID does not exist, reply NAK_RPT</param> /// <param name="sp_id_hd_id">sp_id: Indicate VMC shipment through product ID hd_id: Indicate VMC shipment through cargo lane ID</param> /// <param name="type">If type=0, cost represents the amount of deduction for this shipment. If TYPE is not 0, COST must be 0</param> /// <param name="cost">cost represents the amount of deduction for this shipment</param> public VendoutRpt VENDOUT_IND(byte device, byte method, byte sp_id_hd_id, byte type, int cost) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x83 }; (new byte[] { device, method, sp_id_hd_id, type }); (CommonUtil.Int2ByteArray(cost, 2)); m_CommandList.Add(new Cmd(sendData, new MT(sendData))); if (SendSuccess(0x83, 0x00)) { byte[] receiveData = WaitReceive(0x08); if (receiveData != null) { return new VendoutRpt(receiveData); } } return null; } #endregion #region HUODAO_SET_IND Set the quantity of goods on the cargo route /// <summary> /// PC notifies VMC, the quantity of goods corresponding to the current cargo lane, etc. /// </summary> /// <param name="device">represents the cabinet number</param> /// <param name="huodao">zyxxxxxx "z" Fixed 0 "y" Fixed 0 "xxxxxx", indicating the product margin. If the product margin is greater than 63, it will be unified to 63</param> public bool HUODAO_SET_IND(byte device, List<int> huodao) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x8F }; (device); for (int i = 0; i < ; i++) { if (huodao[i] > 63) { huodao[i] = 63; } } (<byte>(a => (byte)a)); m_CommandList.Add(new Cmd(sendData, new MT(sendData))); return SendSuccess(0x8F, 0x00); } #endregion #region SALEPRICE_IND Set the current product price /// <summary> /// PC notifies VMC, current product price /// </summary> /// <param name="device">represents the cabinet number</param> /// <param name="type"> means the way to set the unit price; Type = 0: To send the unit price according to the product ID, it can be sent in a longer range, with the maximum product types not exceeding 80; Type = 1: To send the unit price information of 80 cargo channels, fixedly send the unit price information of 80 cargo channels</param> /// <param name="sp_price">Product price</param> public bool SALEPRICE_IND(byte device, byte type, List<int> sp_price) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x8E }; (device); (type); (sp_price.ConvertAll<byte>(a => (byte)a)); m_CommandList.Add(new Cmd(sendData, new MT(sendData))); return SendSuccess(0x8E, 0x00); } #endregion #region PAYOUT_IND PC instructs VMC to issue coins /// <summary> /// PC instructs VMC to issue coins /// </summary> /// <param name="device">Coin export device</param> /// <param name="value">Total amount of coins issued this time</param> /// <param name="type">Coin release type There is no need to understand the meaning of type, you only need to pass the type value back to the PC in PAYOUT_RPT after the coin release is completed</param> public PayoutRpt PAYOUT_IND(PayoutType device, int value, byte type) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x89 }; ((byte)device); (CommonUtil.Int2ByteArray(value, 2)); (type); m_CommandList.Add(new Cmd(sendData, new MT(sendData))); if (SendSuccess(0x89, 0x00)) { byte[] receiveData = WaitReceive(0x07); if (receiveData != null) { return new PayoutRpt(receiveData); } } return null; } #endregion #region COST_IND PC deduction instructions /// <summary> /// PC deduction instructions /// </summary> /// <param name="device">device=0, deduct the amount from the total amount of coin input by the user; deduct the amount from the user's non-stage deposit amount (the banknotes should be lagged behind the banknotes as much as possible), see "Cash Deduction Order"</param> /// <param name="value">Deduction amount</param> /// <param name="type">VMC does not need to understand the meaning of type, just pass it back when reporting the corresponding COST_RPT</param> public CostRpt COST_IND(byte device, int value, byte type) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x8B }; (device); (CommonUtil.Int2ByteArray(value, 2)); (type); m_CommandList.Add(new Cmd(sendData, new MT(sendData))); if (SendSuccess(0x8B, 0x00)) { byte[] receiveData = WaitReceive(0x10); if (receiveData != null) { return new CostRpt(receiveData); } } return null; } #endregion #region GET_HUODAO PC notifies VMC to report HUODAO_RPT /// <summary> /// PC notifies VMC to report HUODAO_RPT /// </summary> /// <param name="device">Case number</param> public HuoDaoRpt GET_HUODAO(byte device) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x40, 0x8A }; (device); m_CommandList.Add(new Cmd(sendData)); byte[] receiveData = WaitReceive(0x0E); if (receiveData != null) { return new HuoDaoRpt(receiveData); } return null; } #endregion #region SET_HUODAO PC sends configuration cargo route information /// <summary> /// PC sends configuration cargo route information /// </summary> /// <param name="Cabinet">Cabinet number</param> /// <param name="hd_no">cargo road logic number, decimal</param> /// <param name="Hd_id">Product ID number</param> /// <param name="Hd_count">Remaining volume of cargo lane</param> /// <param name="Hd_price">Unit price of goods route</param> /// <param name="Reserved">Reserved field VMC ignores this field, it is best for the PC to set this field to 0</param> public bool SET_HUODAO(byte Cabinet, int hd_no, int Hd_id, int Hd_count, int Hd_price, int Reserved = 0) { List<byte> sendData = new List<byte>() { 0xE5, 0x00, 0x00, 0x41, 0x93 }; (Cabinet); ((byte)hd_no); ((byte)Hd_id); ((byte)Hd_count); (CommonUtil.Int2ByteArray(Hd_price, 2)); (CommonUtil.Int2ByteArray(Reserved, 2)); m_CommandList.Add(new Cmd(sendData, new MT(sendData))); return SendSuccess(0x93, 0x00); } #endregion #region Turn on the paper coin device /// <summary> /// Cash cash register module (bill device, coin device) switch /// </summary> /// <param name="open">true:Open, false:Off</param> public bool CtrlCoinPaper(bool open) { if (open) { return CONTROL_IND(2, new byte[] { 1 }); } else { return CONTROL_IND(2, new byte[] { 0 }); } } #endregion #region Find change /// <summary> /// Find change /// Same as manually fiddling with physical change switch /// </summary> public bool MakeChange() { return CONTROL_IND(6, new byte[] { 0 }); } #endregion #region Get coin information /// <summary> /// Get coin information /// </summary> public InfoRpt_17 GetCoinInfo() { return new InfoRpt_17(GET_INFO(17)); } #endregion #region Get banknote information /// <summary> /// Get banknote information /// </summary> public InfoRpt_16 GetPaperInfo() { return new InfoRpt_16(GET_INFO(16)); } #endregion #region Get cash coin report /// <summary> /// Get cash coin report /// </summary> public PayinRpt GetPayinRpt() { byte[] receiveData = Receive(0x06, 0x00); if (receiveData != null) { return new PayinRpt(receiveData); } return null; } #endregion #region Get the user's coin balance /// <summary> /// Obtain the user's coin balance /// </summary> public InfoRpt_3 GetRemaiderAmount() { byte[] receiveData = WaitReceive(0x11, 0x003); if (receiveData != null) { return new InfoRpt_3(receiveData); } return null; } #endregion } }
ReceiveDataCollection class and ReceiveData class:
using System; using ; using ; using ; namespace { /// <summary> /// Data received from the serial port (data has been verified) /// </summary> public class ReceiveData { /// <summary> /// Data received from the serial port (data has been verified) /// </summary> public byte[] Data { get; set; } /// <summary> /// Time added to the collection ReceiveDataCollection /// </summary> public DateTime AddTime { get; set; } /// <summary> /// Message type /// </summary> public byte Type { get; set; } /// <summary> /// Message subtype /// </summary> public byte Subtype { get; set; } /// <summary> /// Data received from the serial port (data has been verified) /// </summary> /// <param name="type">Message Type</param> /// <param name="subtype">Message subtype</param> /// <param name="data">Data received from the serial port (data has been verified)</param> /// <param name="addTime">Time to add to the collection ReceiveDataCollection</param> public ReceiveData(byte type, byte subtype, byte[] data, DateTime addTime) { = type; = subtype; = data; = addTime; } } }
using System; using ; using ; using ; namespace { /// <summary> /// Collection of data received from the serial port (data has been verified) /// </summary> public class ReceiveDataCollection { /// <summary> /// Collection of data received from the serial port (data has been verified) /// </summary> private List<ReceiveData> m_ReceiveDataList = new List<ReceiveData>(); /// <summary> /// Data expiration time /// </summary> private int m_Timeout = 3; private static object _lock = new object(); /// <summary> /// Add to collection /// </summary> /// <param name="type">Message Type</param> /// <param name="subtype">Message subtype</param> /// <param name="data">Data received from the serial port (data has been verified)</param> public void Add(byte type, byte subtype, byte[] data) { lock (_lock) { ReceiveData receiveData = new ReceiveData(type, subtype, data, ); m_ReceiveDataList.Add(receiveData); for (int i = m_ReceiveDataList.Count - 1; i >= 0; i--) { if ((m_ReceiveDataList[i].AddTime).TotalMinutes > m_Timeout) { m_ReceiveDataList.RemoveAt(i); } } } } /// <summary> /// Get the data received by the serial port from the collection (the data has been verified) /// </summary> /// <param name="type">Message Type</param> /// <param name="subtype">Message subtype</param> /// <returns>Data received from the serial port (data has been verified)</returns> public byte[] Get(byte type, byte subtype) { lock (_lock) { ReceiveData receiveData = null; for (int i = 0; i < m_ReceiveDataList.Count; i++) { if (m_ReceiveDataList[i].Type == type && m_ReceiveDataList[i].Subtype == subtype) { receiveData = m_ReceiveDataList[i]; m_ReceiveDataList.RemoveAt(i); return ; } } return null; } } /// <summary> /// Get the data received by the serial port from the collection (the data has been verified) /// </summary> /// <param name="type">Message Type</param> /// <returns>Data received from the serial port (data has been verified)</returns> public byte[] Get(byte type) { lock (_lock) { ReceiveData receiveData = null; for (int i = 0; i < m_ReceiveDataList.Count; i++) { if (m_ReceiveDataList[i].Type == type) { receiveData = m_ReceiveDataList[i]; m_ReceiveDataList.RemoveAt(i); return ; } } return null; } } } }
Models:
StatusRpt class:
using System; using ; using ; using ; using MachineJPDll; using ; using ; namespace { /// <summary> /// VMC status report /// </summary> public class StatusRpt { /// <summary> /// Verified data read from the serial port /// </summary> private byte[] m_data; /// <summary> /// VMC status report /// </summary> /// <param name="data">Verified data read from the serial port</param> public StatusRpt(byte[] data) { m_data = data; } public override string ToString() { StringBuilder sb = new StringBuilder(); ("Shipping detection equipment status:{0}\r\n", check_st.ToString()); ("Banknote status:{0}\r\n", bv_st.ToString()); ("Coin stat:{0}\r\n", cc_st.ToString()); ("VMCstate:{0}\r\n", vmc_st.ToString()); ("展示位state:{0} {1} {2} {3}\r\n", pos_st[0].ToString(), pos_st[1].ToString(), pos_st[2].ToString(), pos_st[3].ToString()); ("Total amount of change available in the machine(Including coins and banknotes):{0}\r\n", ()); ("Warehouse1Warehouse2Warehouse3Warehouse4temperature:{0} {1} {2} {3}\r\n", (), (), (), ()); ("Warehousestate设置值:{0} {1} {2} {3}\r\n", tem_st[0].ToString(), tem_st[1].ToString(), tem_st[2].ToString(), tem_st[3].ToString()); if (this.Automatic coin refund == 255) { ("Automatic Coin Refund Time: Never Automatic Coin Refund\r\n"); } else { ("Automatic coin refund时间:{0}\r\n", Automatic coin refund.ToString()); } ("Change margin(1#--6#): {0} {1} {2} {3} {4} {5}\r\n", this. Change margin 1, this. Change margin 2, this. Change margin 3, this. Change margin 4, this. Change margin 5, this. Change margin 6); return (); } /// <summary> /// Delivery equipment status /// </summary> public CheckSt check_st { get { byte val = m_data[5]; return (CheckSt)(val, 0, 2); } } /// <summary> /// Status of banknote /// </summary> public DeviceSt bv_st { get { byte val = m_data[5]; return (DeviceSt)(val, 2, 2); } } /// <summary> /// Coin device status /// </summary> public DeviceSt cc_st { get { byte val = m_data[5]; return (DeviceSt)(val, 4, 2); } } /// <summary> /// VMC status /// </summary> public VmcSt vmc_st { get { byte val = m_data[5]; return (VmcSt)(val, 6, 2); } } /// <summary> /// Showcase status /// </summary> public List<DeviceSt> pos_st { get { List<DeviceSt> deviceStList = new List<DeviceSt>(); byte val = m_data[6]; for (int i = 0; i < 4; i++) { DeviceSt deviceSt = (DeviceSt)(val, i * 2, 2); (deviceSt); } return deviceStList; } } /// <summary> /// The total amount of change available in the machine (including coins and banknotes) /// </summary> public int change { get { return CommonUtil.ByteArray2Int(m_data, 7, 2); } } /// <summary> /// The temperature of the warehouse is 1, 8-digit signed number, this temperature is obtained by the sensor in the warehouse, unit: ℃ /// </summary> public TemSub tem1 { get { return new TemSub(m_data[9]); } } /// <summary> /// The temperature of the warehouse is 2, 8-digit signed number, this temperature is obtained by the sensor in the warehouse, unit: ℃ /// </summary> public TemSub tem2 { get { return new TemSub(m_data[10]); } } /// <summary> /// The temperature of the warehouse is 3, 8 signed numbers, this temperature is obtained by the sensor in the warehouse, unit: ℃ /// </summary> public TemSub tem3 { get { return new TemSub(m_data[11]); } } /// <summary> /// The temperature of the warehouse is 4, 8-digit signed number, this temperature is obtained by the sensor in the warehouse, unit: ℃ /// </summary> public TemSub tem4 { get { return new TemSub(m_data[12]); } } /// <summary> /// The warehouse status setting value, a total of 4 warehouses are supported /// </summary> public List<TemSt> tem_st { get { List<TemSt> temStList = new List<TemSt>(); for (int i = 0; i < 4; i++) { TemSt temSt = (TemSt)(m_data[13], i * 2, 2); (temSt); } return temStList; } } /// <summary> /// Automatic currency refund time. /// 0: It means that the coin will be automatically returned immediately after the product is shipped /// 255: means that the coins will never be automatically returned /// 1-254: It indicates the automatic refund time after the product is shipped (unit: seconds) /// </summary> public int Automatic coin refund { get { return m_data[14]; } } /// <summary> /// The change margin "Refund 1#"…"Refund 6#", corresponding to the "Refund INFO_RPT.type=17" respectively /// 1#"…The number of change for each currency in "Refresh 6#"; /// * The maximum change volume is 255, and it is reported as 255 if it exceeds 255; /// * The unit of change is "piece", which represents the number of change coins. /// </summary> public int Change margin1 { get { return m_data[15]; } } /// <summary> /// The change margin "Refund 1#"…"Refund 6#", corresponding to the "Refund INFO_RPT.type=17" respectively /// 1#"…The number of change for each currency in "Refresh 6#"; /// * The maximum change volume is 255, and it is reported as 255 if it exceeds 255; /// * The unit of change is "piece", which represents the number of change coins. /// </summary> public int Change margin2 { get { return m_data[16]; } } /// <summary> /// The change margin "Refund 1#"…"Refund 6#", corresponding to the "Refund INFO_RPT.type=17" respectively /// 1#"…The number of change for each currency in "Refresh 6#"; /// * The maximum change volume is 255, and it is reported as 255 if it exceeds 255; /// * The unit of change is "piece", which represents the number of change coins. /// </summary> public int Change margin3 { get { return m_data[17]; } } /// <summary> /// The change margin "Refund 1#"…"Refund 6#", corresponding to the "Refund INFO_RPT.type=17" respectively /// 1#"…The number of change for each currency in "Refresh 6#"; /// * The maximum change volume is 255, and it is reported as 255 if it exceeds 255; /// * The unit of change is "piece", which represents the number of change coins. /// </summary> public int Change margin4 { get { return m_data[18]; } } /// <summary> /// The change margin "Refund 1#"…"Refund 6#", corresponding to the "Refund INFO_RPT.type=17" respectively /// 1#"…The number of change for each currency in "Refresh 6#"; /// * The maximum change volume is 255, and it is reported as 255 if it exceeds 255; /// * The unit of change is "piece", which represents the number of change coins. /// </summary> public int Change margin5 { get { return m_data[19]; } } /// <summary> /// The change margin "Refund 1#"…"Refund 6#", corresponding to the "Refund INFO_RPT.type=17" respectively /// 1#"…The number of change for each currency in "Refresh 6#"; /// * The maximum change volume is 255, and it is reported as 255 if it exceeds 255; /// * The unit of change is "piece", which represents the number of change coins. /// </summary> public int Change margin6 { get { return m_data[20]; } } } }
The above is the code for C# to implement the vending machine interface. Friends who need it can learn it.