通过C#实现自动售货机接口
程序员文章站
2023-11-16 23:25:04
下面分几部分介绍c#实现自动售货机接口的方法,代码写的非常详细,不懂的地方有注释可以参考下。
machinejp类:
第1部分:串口初始化,串口数据读写
us...
下面分几部分介绍c#实现自动售货机接口的方法,代码写的非常详细,不懂的地方有注释可以参考下。
machinejp类:
第1部分:串口初始化,串口数据读写
using system; using system.collections.generic; using system.io.ports; using system.linq; using system.text; using system.threading; using system.threading.tasks; using system.windows.forms; using machinejpdll.models; using machinejpdll.utils; namespace machinejpdll { /// <summary> /// 售货机接口(接口) /// </summary> public partial class machinejp { #region 变量 /// <summary> /// 串口资源 /// </summary> private serialport m_serialport = null; /// <summary> /// 待发送给串口的命令列表 /// </summary> private list<cmd> m_commandlist = new list<cmd>(); /// <summary> /// 等待ack_rpt或nak_rpt的pc端向vmc端发送的消息列表 /// </summary> private list<mt> m_waitresultmtlist = new list<mt>(); /// <summary> /// 从串口接收的数据集合(数据已通过验证) /// </summary> private receivedatacollection m_receivedatacollection = new receivedatacollection(); #endregion #region 构造函数与析构函数 /// <summary> /// 售货机接口(接口) /// </summary> public machinejp() { } ~machinejp() { if (m_serialport != null) { m_serialport.close(); m_serialport.dispose(); m_serialport = null; } } #endregion #region 读取串口数据 /// <summary> /// 读取串口数据 /// </summary> /// <returns>从串口读取的数据</returns> private byte[] readport() { //读取串口数据 datetime dt = datetime.now; while (m_serialport.bytestoread < 2) { thread.sleep(1); if (datetime.now.subtract(dt).totalmilliseconds > 1500) //超时 { return new byte[0]; } } list<byte> reclist = new list<byte>(); byte[] recdata = new byte[m_serialport.bytestoread]; m_serialport.read(recdata, 0, recdata.length); reclist.addrange(recdata); int length = recdata[1] + 2; //报文数据总长度 while (reclist.count < length) { if (m_serialport.bytestoread > 0) { recdata = new byte[m_serialport.bytestoread]; m_serialport.read(recdata, 0, recdata.length); reclist.addrange(recdata); } thread.sleep(1); } return reclist.toarray(); } #endregion #region 向串口发送数据 /// <summary> /// 向串口发送数据 /// </summary> /// <param name="cmd">待发送的命令</param> /// <param name="sn">序列号</param> private void writeport(cmd cmd, byte sn) { //发送数据 list<byte> senddata = cmd.data; senddata[1] = (byte)senddata.count; senddata[2] = sn; byte[] checkcode = commonutil.calcheckcode(senddata, senddata.count); senddata.addrange(checkcode); if (cmd.mt != null) { m_waitresultmtlist.add(cmd.mt); } m_serialport.write(senddata.toarray(), 0, senddata.count); loghelper.log(logmsgtype.info, true, senddata.toarray()); } #endregion #region 发送ack消息 /// <summary> /// 发送ack消息 /// </summary> /// <param name="sn">序列号</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 初始化 /// <summary> /// 初始化 /// </summary> /// <param name="com">串口号(例:com1)</param> public void init(string com) { if (m_serialport == null) { m_serialport = new serialport(com, 9600, parity.none, 8, stopbits.one); 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 }); //初始化完成标志 get_status(); setdecimalplaces(2); //设置小数点位数 } #endregion #region close 关闭连接 /// <summary> /// 关闭连接 /// </summary> public void close() { m_serialport.close(); } #endregion #region 接收串口数据 /// <summary> /// 接收串口数据 /// </summary> /// <param name="type">消息类型</param> /// <param name="subtype">消息子类型</param> public byte[] receive(byte type, byte subtype) { return m_receivedatacollection.get(type, subtype); } /// <summary> /// 接收串口数据 /// </summary> /// <param name="type">消息类型</param> /// <param name="subtype">消息子类型</param> public byte[] waitreceive(byte type, byte subtype) { datetime time = datetime.now; while (true) { byte[] receivedata = m_receivedatacollection.get(type, subtype); if (receivedata != null) return receivedata; if (datetime.now.subtract(time).totalminutes > 3) return null; thread.sleep(50); } } /// <summary> /// 接收串口数据 /// </summary> /// <param name="type">消息类型</param> public byte[] waitreceive(byte type) { datetime time = datetime.now; while (true) { byte[] receivedata = m_receivedatacollection.get(type); if (receivedata != null) return receivedata; if (datetime.now.subtract(time).totalminutes > 3) return null; thread.sleep(50); } } #endregion #region 判断消息是否发送成功 /// <summary> /// 判断消息是否发送成功 /// </summary> public bool sendsuccess(byte type, byte subtype) { datetime time = datetime.now; while (true) { if (datetime.now.subtract(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; thread.sleep(1); } } #endregion } }
第2部分:接收串口数据,并响应货机,向货机发送数据
using system; using system.collections.generic; using system.io.ports; using system.linq; using system.text; using machinejpdll.models; using machinejpdll.utils; /* * vmc->pc数据的接收,货机事件的分发 */ namespace machinejpdll { partial class machinejp { #region serialport_datareceived /// <summary> /// 数据接收事件的方法 /// </summary> public void serialport_datareceived(object obj, serialdatareceivedeventargs args) { byte[] receivedata = readport(); if (commonutil.validreceivedata(receivedata)) //只处理验证正确的数据,不正确的数据抛弃不处理 { loghelper.log(logmsgtype.info, false, receivedata); byte sn = commonutil.getsn(receivedata); mt mt = new mt(receivedata); #region 轮询(poll) if (mt.type == 0x03) { if (m_commandlist.count > 0) { writeport(m_commandlist[0], sn); m_commandlist.removeat(0); } else { //发送ack消息 sendack(sn); } } #endregion #region 发送ack消息 if (commonutil.needack(receivedata)) { sendack(sn); //发送ack消息 } #endregion #region vmc系统参数 if (mt.type == 0x05) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region ack_rpt或nak_rpt if (mt.type == 0x01 //ack_rpt || mt.type == 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 数据报告 if (mt.type == 0x11) { #region 纸币器信息 if (mt.subtype == 16) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region 硬币器信息 if (mt.subtype == 17) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region 用户投币余额 if (mt.subtype == 3) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion } #endregion #region vendout_rpt 出货报告 if (mt.type == 0x08) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region status_rpt vmc整机状态报告 if (mt.type == 0x0d) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region saleprice_ind 设置当前商品售价 if (mt.type == 0x8e) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region payin_rpt vmc发送现金投币报告给pc if (mt.type == 0x06) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region payout_rpt 出币报告 if (mt.type == 0x07) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region cost_rpt vmc扣款报告 if (mt.type == 0x10) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region action_rpt 售货机行为报告 if (mt.type == 0x0b) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion #region huodao_rpt vmc货道报告 if (mt.type == 0x0e) { m_receivedatacollection.add(mt.type, mt.subtype, receivedata); } #endregion } else //接收到的数据没有验证通过 { loghelper.logexception(logmsgtype.error, false, "数据异常", receivedata); } } #endregion } }
第3部分:货机状态、投币、出货等接口
using system; using system.collections.generic; using system.linq; using system.text; using system.threading; using machinejpdll.enums; using machinejpdll.models; using machinejpdll.utils; /* * pc->vmc数据的发送(并非直接发送,只是添加到发送列表) */ namespace machinejpdll { partial class machinejp { #region get_setup /// <summary> /// pc通知vmc发送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控制售货机完成对应的动作 /// <summary> /// pc控制vmc /// </summary> public bool control_ind(byte subtype, byte[] value) { list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x85 }; senddata.add(subtype); if (value != null && value.length > 0) { senddata.addrange(value); } m_commandlist.add(new cmd(senddata, new mt(senddata))); return sendsuccess(0x85, subtype); } #endregion #region 设置小数点位数 /// <summary> /// 设置小数点位数 /// 用于pc 通知vmc,双方的金额数据比例系数关系,pc 每次启动时,都会给 /// vmc 下发一次type=18 的消息,vmc 需要自己永久保存该数据,直到被pc 再 /// 次更新。 /// 取值范围:0、1、2 分别表示以 元、 角 、分 为单位 /// </summary> public bool setdecimalplaces(int data) { return control_ind(18, new byte[] { (byte)data }); } #endregion #region get_status pc通知vmc发送status_rpt /// <summary> /// pc通知vmc发送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通知vmc发送info_rpt /// <summary> /// pc通知vmc发送info_rpt /// </summary> public byte[] get_info(byte subtype) { list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x8c }; senddata.add(subtype); m_commandlist.add(new cmd(senddata)); return waitreceive(0x11); } #endregion #region vendout_ind 出货 /// <summary> /// pc出货指示 /// </summary> /// <param name="device">售货机的箱体号 例如柜1 为 0x01 以此类推</param> /// <param name="method">method =1:vmc 通过商品id 指示出货,如果商品id 不存在,回复nak_rpt method =2:vmc 通过货道id 指示vmc 出货,如果货道id 不存在,回复nak_rpt</param> /// <param name="sp_id_hd_id">sp_id:通过商品id 指示vmc 出货 hd_id:通过货道id 指示vmc 出货</param> /// <param name="type">如果type=0,cost 代表本次出货扣款金额 如果type 不为0,则cost 必须为0</param> /// <param name="cost">cost 代表本次出货扣款金额</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 }; senddata.addrange(new byte[] { device, method, sp_id_hd_id, type }); senddata.addrange(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 设置货道商品数量 /// <summary> /// pc通知vmc,当前货道对应商品的数量等信息 /// </summary> /// <param name="device">表示箱柜号</param> /// <param name="huodao">zyxxxxxx “z”固定填0 “y”固定填0 “xxxxxx”,表示商品余量,如果商品余量大于63,则统一为63</param> public bool huodao_set_ind(byte device, list<int> huodao) { list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x8f }; senddata.add(device); for (int i = 0; i < huodao.count; i++) { if (huodao[i] > 63) { huodao[i] = 63; } } senddata.addrange(huodao.convertall<byte>(a => (byte)a)); m_commandlist.add(new cmd(senddata, new mt(senddata))); return sendsuccess(0x8f, 0x00); } #endregion #region saleprice_ind 设置当前商品售价 /// <summary> /// pc通知vmc,当前商品售价 /// </summary> /// <param name="device">表示箱柜号</param> /// <param name="type">表示设置单价的方式;type = 0:为按商品id 发送单价,可以变长发送,商品种类最大不超过80 个;type = 1: 为按货道号发送,固定发送80 个货道的单价信息</param> /// <param name="sp_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 }; senddata.add(device); senddata.add(type); senddata.addrange(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指示vmc出币 /// <summary> /// pc指示vmc出币 /// </summary> /// <param name="device">出币设备</param> /// <param name="value">本次出币总金额</param> /// <param name="type">出币类型 无需理解type 的含义,只需要在出币完成后的payout_rpt 中将该type 值回传给pc 即可</param> public payoutrpt payout_ind(payouttype device, int value, byte type) { list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x89 }; senddata.add((byte)device); senddata.addrange(commonutil.int2bytearray(value, 2)); senddata.add(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扣款指示 /// <summary> /// pc扣款指示 /// </summary> /// <param name="device">device=0,从用户投币总额中扣款;优先从用户非暂存金额中扣除(纸币尽量滞后压钞),参见《现金扣款顺序》</param> /// <param name="value">扣款金额</param> /// <param name="type">vmc 不用理解type 的含义,只需上报对应的cost_rpt 时回传即可</param> public costrpt cost_ind(byte device, int value, byte type) { list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x41, 0x8b }; senddata.add(device); senddata.addrange(commonutil.int2bytearray(value, 2)); senddata.add(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通知vmc上报huodao_rpt /// <summary> /// pc通知vmc上报huodao_rpt /// </summary> /// <param name="device">箱柜号</param> public huodaorpt get_huodao(byte device) { list<byte> senddata = new list<byte>() { 0xe5, 0x00, 0x00, 0x40, 0x8a }; senddata.add(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发送配置货道信息 /// <summary> /// pc发送配置货道信息 /// </summary> /// <param name="cabinet">箱柜号</param> /// <param name="hd_no">货道逻辑编号,十进制</param> /// <param name="hd_id">商品id号</param> /// <param name="hd_count">货道剩余量</param> /// <param name="hd_price">货道单价</param> /// <param name="reserved">保留字段vmc忽略此字段,pc最好将此字段置为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 }; senddata.add(cabinet); senddata.add((byte)hd_no); senddata.add((byte)hd_id); senddata.add((byte)hd_count); senddata.addrange(commonutil.int2bytearray(hd_price, 2)); senddata.addrange(commonutil.int2bytearray(reserved, 2)); m_commandlist.add(new cmd(senddata, new mt(senddata))); return sendsuccess(0x93, 0x00); } #endregion #region 开启纸硬币器 /// <summary> /// 现金收银模组(纸币器、硬币器)开关 /// </summary> /// <param name="open">true:开,false:关</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 找零 /// <summary> /// 找零 /// 与手工拨弄物理找零开关相同 /// </summary> public bool makechange() { return control_ind(6, new byte[] { 0 }); } #endregion #region 获取硬币器信息 /// <summary> /// 获取硬币器信息 /// </summary> public inforpt_17 getcoininfo() { return new inforpt_17(get_info(17)); } #endregion #region 获取纸币器信息 /// <summary> /// 获取纸币器信息 /// </summary> public inforpt_16 getpaperinfo() { return new inforpt_16(get_info(16)); } #endregion #region 获取现金投币报告 /// <summary> /// 获取现金投币报告 /// </summary> public payinrpt getpayinrpt() { byte[] receivedata = receive(0x06, 0x00); if (receivedata != null) { return new payinrpt(receivedata); } return null; } #endregion #region 获取用户投币余额 /// <summary> /// 获取用户投币余额 /// </summary> public inforpt_3 getremaideramount() { byte[] receivedata = waitreceive(0x11, 0x003); if (receivedata != null) { return new inforpt_3(receivedata); } return null; } #endregion } }
receivedatacollection类和receivedata类:
using system; using system.collections.generic; using system.linq; using system.text; namespace machinejpdll.models { /// <summary> /// 从串口接收到的数据(数据已通过验证) /// </summary> public class receivedata { /// <summary> /// 从串口接收到的数据(数据已通过验证) /// </summary> public byte[] data { get; set; } /// <summary> /// 添加到集合receivedatacollection的时间 /// </summary> public datetime addtime { get; set; } /// <summary> /// 消息类型 /// </summary> public byte type { get; set; } /// <summary> /// 消息子类型 /// </summary> public byte subtype { get; set; } /// <summary> /// 从串口接收到的数据(数据已通过验证) /// </summary> /// <param name="type">消息类型</param> /// <param name="subtype">消息子类型</param> /// <param name="data">从串口接收到的数据(数据已通过验证)</param> /// <param name="addtime">添加到集合receivedatacollection的时间</param> public receivedata(byte type, byte subtype, byte[] data, datetime addtime) { this.type = type; this.subtype = subtype; this.data = data; this.addtime = addtime; } } }
using system; using system.collections.generic; using system.linq; using system.text; namespace machinejpdll.models { /// <summary> /// 从串口接收到的数据集合(数据已通过验证) /// </summary> public class receivedatacollection { /// <summary> /// 从串口接收到的数据集合(数据已通过验证) /// </summary> private list<receivedata> m_receivedatalist = new list<receivedata>(); /// <summary> /// 数据过期时间 /// </summary> private int m_timeout = 3; private static object _lock = new object(); /// <summary> /// 添加到集合 /// </summary> /// <param name="type">消息类型</param> /// <param name="subtype">消息子类型</param> /// <param name="data">从串口接收到的数据(数据已通过验证)</param> public void add(byte type, byte subtype, byte[] data) { lock (_lock) { receivedata receivedata = new receivedata(type, subtype, data, datetime.now); m_receivedatalist.add(receivedata); for (int i = m_receivedatalist.count - 1; i >= 0; i--) { if (datetime.now.subtract(m_receivedatalist[i].addtime).totalminutes > m_timeout) { m_receivedatalist.removeat(i); } } } } /// <summary> /// 从集合中获取串口接收到的数据(数据已通过验证) /// </summary> /// <param name="type">消息类型</param> /// <param name="subtype">消息子类型</param> /// <returns>从串口接收到的数据(数据已通过验证)</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 receivedata.data; } } return null; } } /// <summary> /// 从集合中获取串口接收到的数据(数据已通过验证) /// </summary> /// <param name="type">消息类型</param> /// <returns>从串口接收到的数据(数据已通过验证)</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 receivedata.data; } } return null; } } } }
models:
statusrpt类:
using system; using system.collections.generic; using system.linq; using system.text; using machinejpdll; using machinejpdll.enums; using machinejpdll.utils; namespace machinejpdll.models { /// <summary> /// vmc状态报告 /// </summary> public class statusrpt { /// <summary> /// 从串口读取的通过验证的数据 /// </summary> private byte[] m_data; /// <summary> /// vmc状态报告 /// </summary> /// <param name="data">从串口读取的通过验证的数据</param> public statusrpt(byte[] data) { m_data = data; } public override string tostring() { stringbuilder sb = new stringbuilder(); sb.appendformat("出货检测设备状态:{0}\r\n", check_st.tostring()); sb.appendformat("纸币器状态:{0}\r\n", bv_st.tostring()); sb.appendformat("硬币器状态:{0}\r\n", cc_st.tostring()); sb.appendformat("vmc状态:{0}\r\n", vmc_st.tostring()); sb.appendformat("展示位状态:{0} {1} {2} {3}\r\n", pos_st[0].tostring(), pos_st[1].tostring(), pos_st[2].tostring(), pos_st[3].tostring()); sb.appendformat("机器中可用的找零量总金额(包括硬币和纸币):{0}\r\n", change.tostring()); sb.appendformat("货仓1货仓2货仓3货仓4温度:{0} {1} {2} {3}\r\n", tem1.tostring(), tem2.tostring(), tem3.tostring(), tem4.tostring()); sb.appendformat("货仓状态设置值:{0} {1} {2} {3}\r\n", tem_st[0].tostring(), tem_st[1].tostring(), tem_st[2].tostring(), tem_st[3].tostring()); if (this.自动退币 == 255) { sb.appendformat("自动退币时间:永不自动退币\r\n"); } else { sb.appendformat("自动退币时间:{0}\r\n", 自动退币.tostring()); } sb.appendformat("找零余量(1#--6#):{0} {1} {2} {3} {4} {5}\r\n", this.找零余量1, this.找零余量2, this.找零余量3, this.找零余量4, this.找零余量5, this.找零余量6); return sb.tostring(); } /// <summary> /// 出货检测设备状态 /// </summary> public checkst check_st { get { byte val = m_data[5]; return (checkst)commonutil.getfrombyte(val, 0, 2); } } /// <summary> /// 纸币器状态 /// </summary> public devicest bv_st { get { byte val = m_data[5]; return (devicest)commonutil.getfrombyte(val, 2, 2); } } /// <summary> /// 硬币器状态 /// </summary> public devicest cc_st { get { byte val = m_data[5]; return (devicest)commonutil.getfrombyte(val, 4, 2); } } /// <summary> /// vmc状态 /// </summary> public vmcst vmc_st { get { byte val = m_data[5]; return (vmcst)commonutil.getfrombyte(val, 6, 2); } } /// <summary> /// 展示位状态 /// </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)commonutil.getfrombyte(val, i * 2, 2); devicestlist.add(devicest); } return devicestlist; } } /// <summary> /// 机器中,可用的找零量总金额(包括硬币和纸币) /// </summary> public int change { get { return commonutil.bytearray2int(m_data, 7, 2); } } /// <summary> /// 货仓1 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃ /// </summary> public temsub tem1 { get { return new temsub(m_data[9]); } } /// <summary> /// 货仓2 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃ /// </summary> public temsub tem2 { get { return new temsub(m_data[10]); } } /// <summary> /// 货仓3 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃ /// </summary> public temsub tem3 { get { return new temsub(m_data[11]); } } /// <summary> /// 货仓4 温度,8 位有符号数,该温度通过货仓内传感器获取,单位:℃ /// </summary> public temsub tem4 { get { return new temsub(m_data[12]); } } /// <summary> /// 货仓状态设置值,共支持4 个货仓 /// </summary> public list<temst> tem_st { get { list<temst> temstlist = new list<temst>(); for (int i = 0; i < 4; i++) { temst temst = (temst)commonutil.getfrombyte(m_data[13], i * 2, 2); temstlist.add(temst); } return temstlist; } } /// <summary> /// 自动退币时间。 /// 0:表示商品出货后,立即自动退币 /// 255:表示永不自动退币 /// 1-254:表示商品出货后,自动退币时间(单位:秒) /// </summary> public int 自动退币 { get { return m_data[14]; } } /// <summary> /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零 /// 1#”…“找零6#”中每种钱币的找零数量; /// * 找零量最大为255,超过255 时上报为255; /// * 找零量单位为“个”,代表可找零硬币的个数。 /// </summary> public int 找零余量1 { get { return m_data[15]; } } /// <summary> /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零 /// 1#”…“找零6#”中每种钱币的找零数量; /// * 找零量最大为255,超过255 时上报为255; /// * 找零量单位为“个”,代表可找零硬币的个数。 /// </summary> public int 找零余量2 { get { return m_data[16]; } } /// <summary> /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零 /// 1#”…“找零6#”中每种钱币的找零数量; /// * 找零量最大为255,超过255 时上报为255; /// * 找零量单位为“个”,代表可找零硬币的个数。 /// </summary> public int 找零余量3 { get { return m_data[17]; } } /// <summary> /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零 /// 1#”…“找零6#”中每种钱币的找零数量; /// * 找零量最大为255,超过255 时上报为255; /// * 找零量单位为“个”,代表可找零硬币的个数。 /// </summary> public int 找零余量4 { get { return m_data[18]; } } /// <summary> /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零 /// 1#”…“找零6#”中每种钱币的找零数量; /// * 找零量最大为255,超过255 时上报为255; /// * 找零量单位为“个”,代表可找零硬币的个数。 /// </summary> public int 找零余量5 { get { return m_data[19]; } } /// <summary> /// 找零余量“找零量1#”…“找零量6#”,分别对应硬币器信息info_rpt.type=17 的“找零 /// 1#”…“找零6#”中每种钱币的找零数量; /// * 找零量最大为255,超过255 时上报为255; /// * 找零量单位为“个”,代表可找零硬币的个数。 /// </summary> public int 找零余量6 { get { return m_data[20]; } } } }
以上就是c#实现自动售货机接口的代码,需要的朋友可以来学习。
上一篇: C#窗口实现单例模式的方法