您好!欢迎来到默认站点! 请登录 注册有礼
首页 新闻资讯 > 研发日志 > 物联网

物联网RFID开发三:获取设备配置信息

2020-3-25 17:46:00 人评论

首先建立设备配置信息数据实体,编写通过Socket连接向网络设备发送命令方法,此方法将被多个方法调用,完成与RFID读头设备建立连接后,向其发送指令并获取回复消息

首先建立设备配置信息数据实体,继承自ReaderDevice,扩展了详细配置属性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mvcms.Common.Net {
    /// <summary>
    /// RD915-2000读写器设备配置数据实体
    /// </summary>
    public class ReaderDeviceSetting: ReaderDevice {
        public ReaderDeviceSetting() {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="index">序号索引</param>
        /// <param name="ipaddress">设备IP地址</param>
        /// <param name="receiveBytes">接收到的数据</param>
        public ReaderDeviceSetting(string ipaddress, byte[] receiveBytes)
            : base(ipaddress, receiveBytes) {
        }
        
        /// <summary>
        /// 读写器连接端口对应的句柄
        /// </summary>
        public int FrmHandle;

        /// <summary>
        /// 远距离读写器的地址。以广播地址(0xFF)调用此函数,ComAdr将返回读写器的实际地址
        /// </summary>
        public byte ComAddress { get; set; }

        /// <summary>
        /// 设备版本号
        /// </summary>
        public string Version { get; set; }

        /// <summary>
        /// 读写器类型代码,0x0d代表UHFREADER188
        /// </summary>
        public byte ReaderType;

        /// <summary>
        /// 读写器协议支持信息,bit1为1表示支持18000-6c协议
        /// </summary>
        public byte[] TrType;

        /// <summary>
        /// 输出变量,Bit7-Bit6用于频段设置用;Bit5-Bit0表示当前读写器工作的最大频率
        /// </summary>
        public byte MaxFre{ get; set; }

        /// <summary>
        /// 输出变量, 输出变量, Bit7-Bit6用于频段设置用;Bit5-Bit0表示当前读写器工作的最小频率
        /// </summary>
        public byte MinFre{ get; set; }

        /// <summary>
        /// 读写器的输出功率。范围是0到30
        /// </summary>
        public byte PowerDbm { get; set; }

        /// <summary>
        /// 读写器询查命令最大响应时间
        /// </summary>
        public byte ScanTime { get; set; }

        /// <summary>
        /// 传输协议
        /// </summary>
        public int TransferProtocol { get; set; }
        /// <summary>
        /// 工作模式
        /// </summary>
        public int RunMode { get; set; }
        /// <summary>
        /// 连接方式
        /// </summary>
        public int ConnectionMode { get; set; }
        /// <summary>
        /// 连接时限
        /// </summary>
        public int ConnectionTime { get; set; }
        public string fc = "";
        public string dt = "";
        public string br = "";
        public string pr = "";
        public string bb = "";
        public string rc = "";
        public string ml = "";
        public string md = "";

        /// <summary>
        /// 网关IP地址
        /// </summary>
        public string Gateway { get; set; }
        /// <summary>
        /// 子网掩码
        /// </summary>
        public string SubnetMask { get; set; }

        #region 只读属性
        /// <summary>
        /// 读写器地址,十六进制字符串
        /// </summary>
        public string AddressText {
            get {
                return Convert.ToString(ComAddress, 16).PadLeft(2, '0');
            }
        }

        /// <summary>
        /// 频段
        /// </summary>
        public byte FrequencyBand {
            get {
                return Convert.ToByte(((MaxFre & 0xc0) >> 4) | (MinFre >> 6));
            }
        }

        /// <summary>
        /// 最小频率
        /// </summary>
        public double MinFrequency {
            get {
                //最小频率,最大频率
                double result = 0;
                switch (FrequencyBand) {
                    case 1: {
                            result = 920.125 + (MinFre & 0x3F) * 0.25;
                        }
                        break;
                    case 2: {
                            result = 902.75 + (MinFre & 0x3F) * 0.5;
                        }
                        break;
                    case 3: {
                            result = 917.1 + (MinFre & 0x3F) * 0.2;
                        }
                        break;
                    case 4: {
                            result = 865.1 + (MinFre & 0x3F) * 0.2;
                        }
                        break;
                }
                return result;
            }
        }

        /// <summary>
        /// 最大频率
        /// </summary>
        public double MaxFrequency {
            get {
                //最小频率,最大频率
                double result = 0;
                switch (FrequencyBand) {
                    case 1: {
                            result = 920.125 + (MaxFre & 0x3F) * 0.25;
                        }
                        break;
                    case 2: {
                            result = 902.75 + (MaxFre & 0x3F) * 0.5;
                        }
                        break;
                    case 3: {
                            result = 917.1 + (MaxFre & 0x3F) * 0.2;
                        }
                        break;
                    case 4: {
                            result = 865.1 + (MaxFre & 0x3F) * 0.2;
                        }
                        break;
                }
                return result;
            }
        }

        /// <summary>
        /// 单频点
        /// </summary>
        public bool SingleFrequencyPoint {
            get {
                //是否单频点
                if ((Convert.ToInt32(MaxFrequency) & 0x3F) != (Convert.ToInt32(MinFrequency) & 0x3F)) {
                    return true;
                }
                else {
                    return false;
                }
            }
        }

        /// <summary>
        /// 设备类型
        /// </summary>
        public string ReaderTypeName {
            get {
                //设备类型
                if (ReaderType == 0x0d) {
                    return "UHFReader188";
                }
                else {
                    return "未知型号";
                }
            }
        }
        #endregion
    }
}

编写通过Socket连接向网络设备发送命令方法,完成与RFID读头设备建立连接后,向其发送指令并获取回复消息

/// <summary>
/// 向指定设备发送一条命令文本
/// </summary>
/// <param name="socket">socked连接实例</param>
/// <param name="ipEndPoint">ip地址</param>
/// <param name="requestText">命令文本</param>
/// <param name="sleep">休眠时间(毫秒)</param>
/// <param name="endPoint"></param>
/// <returns></returns>
private byte[] SendCommand(Socket socket, IPEndPoint ipEndPoint, byte[] sendBytes, int sleep) {
    byte[] result = null;
    EndPoint endPoint = (EndPoint)ipEndPoint;
    try {
        for (int i = 0; i < 3; i++ ) {
            socket.SendTo(sendBytes, ipEndPoint);
            if (sleep > 0) {
                Thread.Sleep(sleep);
            }
            byte[] buffer = new byte[1000];
            socket.ReceiveTimeout = 10;
            int m_count = socket.ReceiveFrom(buffer, ref endPoint);
            if (m_count > 0) {
                byte[] receiveBytes = new byte[m_count];
                Array.Copy(buffer, receiveBytes, m_count);
                result = receiveBytes;
                break;
            }
        }
    }
    catch (Exception e) {
        message = e.Message;
    }
    return result;
}

/// <summary>
/// 向指定设备发送一条命令文本
/// </summary>
/// <param name="socket">socked连接实例</param>
/// <param name="ipEndPoint">ip地址</param>
/// <param name="requestText">命令文本</param>
/// <param name="sleep">休眠时间(毫秒)</param>
/// <param name="endPoint"></param>
/// <returns></returns>
private string SendCommand(Socket socket, IPEndPoint ipEndPoint, string requestText, int sleep) {
    string result = string.Empty;
    byte[] sendBytes = Encoding.ASCII.GetBytes(requestText);
    byte[] receiveBytes = SendCommand(socket, ipEndPoint, sendBytes, sleep);
    string receiveText = Encoding.ASCII.GetString(receiveBytes);
    if (receiveText.IndexOf('A') == 0) {
        result = receiveText;
    }
    else {
        message = "回复内容格式错误!";
    }
    return result;
}

编写获取设备配置信息方法,此方法将向设备发送多条执行,获取设备详细配置信息,并保存到DeviceSetting数据实体对象,供控制器和视图使用

/// <summary>
/// 获取设备配置信息
/// </summary>
/// <param name="ipaddress">设备IP地址字符串</param>
/// <param name="port">设备端口</param>
/// <returns></returns>
public ReaderDeviceSetting GetDeviceSetting(string ipaddress, int port) {
    ReaderDeviceSetting result = null;
    //初始化一个Socket实例,采用UDP传输
    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
        //设置该Socket实例的发送形式
        socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
        result = GetDeviceSetting(socket, ipaddress, port);//发送了21条指令来获取设备详细配置信息
        socket.Close();//注意及时释放资源
    }
    return result;
}

/// <summary>
/// 获取设备配置信息
/// </summary>
/// <param name="socket">Socket连接实例</param>
/// <param name="ipaddress">IP地址</param>
/// <param name="port">端口</param>
/// <returns></returns>
private ReaderDeviceSetting GetDeviceSetting(Socket socket, string ipaddress, int port) {
    ReaderDeviceSetting result = null;
    IPAddress ip = IPAddress.Parse(ipaddress);
    IPEndPoint ipEndPoint = new IPEndPoint(ip, 65535);//初始化一个发送广播和指定端口的网络端口实例
    EndPoint endPoint = (EndPoint)ipEndPoint;

    string request = "X";//获取设备基本信息
    byte[] sendData = Encoding.ASCII.GetBytes(request);
    byte[] receiveData = SendCommand(socket, ipEndPoint, sendData, 0);
    if (receiveData == null) {
        return null;
    }
    //由终端回复内容创建基础设备信息
    result = new ReaderDeviceSetting(ipaddress, receiveData);
    if (!result.IsReaderDevice) {//判断是否RFID读头设备
        return null;
    }

    request = "W" + result.MAC;//获取设备配置信息,效验是否为UFH设备,正确回复:A
    string receiveText = SendCommand(socket, ipEndPoint, request, 100);

    request = "L";//回复示例:A
    receiveText = SendCommand(socket, ipEndPoint, request, 50);

    request = "GON|1";//获取设备用户名称,回复示例:ARD915MU|1
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    int index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "1") {
        result.SubName = receiveText.Substring(1, index - 1);
    }

    request = "GDN|2";//获取设备名称,回复示例:ARD915MD:2
    receiveText = SendCommand(socket, ipEndPoint, request, 0);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "2") {
        result.Name = receiveText.Substring(1, index - 1);
    }

    request = "GFE|3";//获取设备MAC地址,回复示例:A0.34.111.253.138.91|3
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "3") {
        result.MAC = receiveText.Substring(1, index - 1);
    }

    request = "GIP|4";//获取设备IP地址,回复示例:A10.100.100.254|4
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "4") {
        result.RemoteIPAddress = receiveText.Substring(1, index - 1);
    }

    request = "GPN|5";//获取设备端口号,回复示例:A6000|5
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "5") {
        result.RemotePort = int.Parse(receiveText.Substring(1, index - 1));
    }

    request = "GTP|6";//获取设备传输协议,回复示例:A1|6
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "6") {
        result.TransferProtocol = int.Parse(receiveText.Substring(1, index - 1));
    }

    request = "GRM|7";//获取设备工作模式,回复示例:A1|7
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "7") {
        result.RunMode = int.Parse(receiveText.Substring(1, index - 1));
    }

    request = "GCM|8";//获取设备连接方式,回复示例:A1|8
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "8") {
        result.ConnectionMode = int.Parse(receiveText.Substring(1, index - 1));
    }

    request = "GCT|9";//获取设备连接时限,回复示例:A6|9
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 1) == "9") {
        result.ConnectionTime = int.Parse(receiveText.Substring(1, index - 1));
    }

    request = "GFC|10";//获取设备?,回复示例:A0|10
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "10") {
        result.fc = receiveText.Substring(1, index - 1);
    }

    request = "GDT|11";//获取设备?,回复示例:A0|11
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "11") {
        result.dt = receiveText.Substring(1, index - 1);
    }

    request = "GBR|12";//获取设备?,回复示例:A6|12
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "12") {
        result.br = receiveText.Substring(1, index - 1);
    }

    request = "GPR|13";//获取设备?,回复示例:A0:13
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "13") {
        result.pr = receiveText.Substring(1, index - 1);
    }

    request = "GBB|14";//获取设备?,回复示例:A0|14
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "14") {
        result.bb = receiveText.Substring(1, index - 1);
    }

    request = "GRC|15";//获取设备?,回复示例:A0|15
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "15") {
        result.rc = receiveText.Substring(1, index - 1);
    }

    request = "GML|16";//获取设备?,回复示例:A255|16
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "16") {
        result.ml = receiveText.Substring(1, index - 1);
    }

    request = "GMD|17";//获取设备?,回复示例:A0|17
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "17") {
        result.md = receiveText.Substring(1, index - 1);
    }

    request = "GDI|18";//获取设备上报数据IP地址,回复示例:A10.100.100.251|18
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "18") {
        result.LocalIPAddress = receiveText.Substring(1, index - 1);
    }

    request = "GDP|19";//获取设备上报数据端口号,回复示例:A30915|19
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "19") {
        result.LocalPort = int.Parse(receiveText.Substring(1, index - 1));
    }

    request = "GGI|20";//获取设备网关地址,回复示例:A10.100.100.1|20
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "20") {
        result.Gateway = receiveText.Substring(1, index - 1);
    }

    request = "GNM|21";//获取设备子网掩码,回复示例:A255.255.255.0|21
    receiveText = SendCommand(socket, ipEndPoint, request, 10);
    index = receiveText.IndexOf('|');
    if (receiveText.Substring(index + 1, 2) == "21") {
        result.SubnetMask = receiveText.Substring(1, index - 1);
    }
    return result;
}

控制器代码,需要列表页面传入IP地址和端口号,指定要访问的设备

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Net;
using Mvcms.Common.Net;

namespace Mvcms.Web.Controllers.admin.IOT {
    public class device_editController: UI.Controllers.BaseManageController {
        public ActionResult Index() {
            string ipaddress = request.QueryString["ip"].Trim();
            int port = request.QueryString["port"].ToInt();
            IsPlugin = true;
            ReaderDeviceHelper helper = new ReaderDeviceHelper();
            ReaderDeviceSetting model = helper.GetDeviceSetting(ipaddress, port);
            return View(GetViewName("/IOT/device_edit.cshtml"), model);
        }
    }
}

视图局部代码,将控制传入的DeviceSetting数据实体对象在前台显示

@model Mvcms.Entities.IOT.DeviceSetting
<form id="form1" method="post" action="SubmitSave?action=@ViewBag.action&id=@ViewBag.id">
    <!--导航栏-->
    <div class="location">
        <a href="../card_list/index" class="back"><i class="iconfont icon-up"></i><span>返回列表页</span></a>
        <a href="../../center/index"><i class="iconfont icon-home"></i><span>首页</span></a>
        <i class="arrow iconfont icon-arrow-right"></i>
        <a href="../card_list/index"><span>管理</span></a>
        <i class="arrow iconfont icon-arrow-right"></i>
        <span>编辑</span>
        <div class="clipboard">
            <span>
                <label id="clipMess"></label>
            </span>
            <a href="javascript:;" class="copy" onclick="copy();"><i class="iconfont icon-copy"></i><span>复制</span></a>
            <a href="javascript:;" class="paste disable" onclick="paste();"><i class="iconfont icon-log"></i><span>粘贴</span></a>
        </div>
    </div>
    <div class="line10"></div>
    <!--/导航栏-->

    <!--内容-->
    <div id="floatHead" class="content-tab-wrap">
        <div class="content-tab">
            <div class="content-tab-ul-wrap">
                <ul>
                    <li><a class="selected" href="javascript:;">基本信息</a></li>
                </ul>
            </div>
        </div>
    </div>

    <div class="tab-content">
        <dl>
            <dt>设备名称</dt>
            <dd>
                <input id="Name" name="Name" class="input" value="@Model.Name" datatype="s1-8" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>用户名称</dt>
            <dd>
                <input id="SubName" name="SubName" class="input" value="@Model.SubName" datatype="s1-8" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>MAC地址</dt>
            <dd>
                <input id="MAC" name="MAC" class="input" value="@Model.MAC" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>IP地址</dt>
            <dd>
                <input id="IPAddress" name="IPAddress" class="input" value="@Model.RemoteIPAddress" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>端口号</dt>
            <dd>
                <input id="Port" name="Port" class="input" value="@Model.RemotePort" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>传输协议</dt>
            <dd>
                <div class="rule-single-select">
                    <select id="TransferProtocol" name="TransferProtocol">
                        <option value="0" @(Model.TransferProtocol == 0 ? "selected=selected" : "")>UDP</option>
                        <option value="1" @(Model.TransferProtocol == 1 ? "selected=selected" : "")>TCP</option>
                    </select>
                </div>
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>工作模式</dt>
            <dd>
                <div class="rule-single-select">
                    <select id="RunMode" name="RunMode">
                        <option value="0" @(Model.RunMode == 0 ? "selected=selected" : "")>服务端</option>
                        <option value="1" @(Model.RunMode == 1 ? "selected=selected" : "")>服务端和客户端</option>
                        <option value="2" @(Model.RunMode == 2 ? "selected=selected" : "")>客户端</option>
                    </select>
                </div>
            </dd>
        </dl>
        <dl>
            <dt>目标IP地址</dt>
            <dd>
                <input id="DestinationIP" name="DestinationIP" class="input" value="@Model.LocalIPAddress" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>目标端口</dt>
            <dd>
                <input id="DestinationPort" name="DestinationPort" class="input" value="@Model.LocalPort" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>网关IP地址</dt>
            <dd>
                <input id="Gateway" name="Gateway" class="input normal" value="@Model.Gateway" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>子网掩码</dt>
            <dd>
                <input id="SubnetMask" name="SubnetMask" class="input normal" value="@Model.SubnetMask" datatype="*" />
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>连接方式</dt>
            <dd>
                <div class="rule-single-select">
                    <select id="ConnectionMode" name="ConnectionMode">
                        <option value="0" @(Model.ConnectionMode == 0 ? "selected=selected" : "")>立即连接</option>
                        <option value="1" @(Model.ConnectionMode == 1 ? "selected=selected" : "")>有数据才连接</option>
                    </select>
                </div>
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
        <dl>
            <dt>连接时限</dt>
            <dd>
                <div class="rule-single-select">
                    <select id="ConnectionTime" name="ConnectionTime" style="width: 60px;">
                        @for (int i = 0; i < 100; i++) {
                            <option value="@i" @(Model.ConnectionTime == i ? "selected=selected" : "")>@i</option>
                        }
                    </select>
                </div>
                <span class="Validform_checktip"></span>
            </dd>
        </dl>
    </div>
    <!--/内容-->

    <!--工具栏-->
    <div class="page-footer">
        <div class="btn-wrap">
            <input type="submit" id="btnSubmit" class="btn" value="提交保存" />
            <input name="btnReturn" type="button" value="返回上一页" class="btn yellow" onclick="javascript: history.back(-1);" />
        </div>
    </div>
    <!--/工具栏-->
</form>


界面截图,可以设置读头设备的网络配置,高级参数(功率、工作模式等)需要COM口连接才可以配置,不过高级参数只需要上线前配置一次,运行中可能需要修改的配置主要还是相关IP配置。

image.png

相关资讯

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?
    会员登陆
    18004549898
    QQ
    Mvcms网站管理系统客服QQ:
    返回顶部