【云原生】设备入云之基于FlexManager的应用开发


前言

上几篇介绍了FlexManager设备云端数据的各种操作,相信大家都有看了。本篇开始,将就怎么使用设备云数据库的数据进行客户端应用开发的方式逐一介绍。当然,最基层的设备入云得基本掌握一点自动化的一些相关知识,同学们如果有兴趣可以到我的学习资料里边去学习一波,此处不做重点讲述。本文重点讲述的是基于FlexManager的Visual Studio应用开发。


`特别说明:
1、适用于 Visual Studio版本号15.3及以上。
2、需要引入NuGet依赖包FBoxClientDriver、FBoxClientDriver.Contract。

一、Visual Studio应用开发

1、流程步骤

①配置参数
②创建DefaultCredentialProvider对象

③创建FBoxClientManager对象
④登录服务器

⑤侦听盒子状态变更事件
⑥侦听实时数据推送变更事件

⑦开启盒子的所有监控点数据推送

⑧定义方法
⑨调用方法

2、示例代码

注意:数据推送前需要先开点

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using FBoxClientDriver;
using FBoxClientDriver.Contract;
using FBoxClientDriver.Impl;

namespace SDKDEMO
{
    
    
    //配置参数
    public class FBoxClientParameters
    {
    
    
        public static string ClientId {
    
     get; set; } = "";
        public static string ClientSecret {
    
     get; set; } = "";
        public static string UserName {
    
     get; set; } = "";
        public static string Password {
    
     get; set; } = "";
        public static string IdServer {
    
     get; set; } = "https://account.flexem.com/core";
        public static string MainServer {
    
     get; set; } = "http://fbox360.com";
        public static string HdataServer {
    
     get; set; } = "http://fbhs1.fbox360.com";
    }

    public class FBoxDemo : IDisposable
    {
    
    
        private readonly IFBoxClientManager _fbox;
        private readonly string boxNo = "300015050009"; // 以这个为例子

        public FBoxDemo()
        {
    
    
            //创建对象并初始化
            var provider =
                new DefaultCredentialProvider(FBoxClientParameters.ClientId, FBoxClientParameters.ClientSecret,
                    FBoxClientParameters.UserName, FBoxClientParameters.Password);
            _fbox = new FBoxClientManager(FBoxClientParameters.IdServer, FBoxClientParameters.MainServer,
                FBoxClientParameters.HdataServer, provider, Guid.NewGuid().ToString("N"), null);
        }

        public void Dispose()
        {
    
    
            _fbox?.Dispose();
        }

       /// <summary>
        /// 启动
        /// </summary>
        public void Start()
        {
    
    
            //初始化SDK,内部建立signalr连接对象,Restart只需全局执行一次。
            _fbox.Restart().Wait();
            //侦听盒子状态变更事件
            _fbox.BoxConnectStateChanged += _fbox_BoxConnectStateChanged;
            //侦听实时数据变更事件
            _fbox.DataMonitorValueChanged += _fbox_DataMonitorValueChanged;
        }

        /// <summary>
        /// 实时数据变更函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _fbox_DataMonitorValueChanged(object sender, IList<DataMonitorValueChangedArgs> e)
        {
    
    
            foreach (var dmon in e)
                Console.WriteLine($"dmv:{dmon.Uid}:{dmon.Value},{dmon.Status}");
        }

        /// <summary>
        /// 盒子状态变更函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _fbox_BoxConnectStateChanged(object sender, IList<BoxConnectionStateItem> e)
        {
    
    
            //NewState:1、2是盒子在线状态。0、3为盒子不在线状态,根据盒子状态对盒子进行开点操作
            foreach (var stateItem in e)
            {
    
    
                Console.WriteLine($"{stateItem.BoxNo},{stateItem.NewState}");
            }
        }

        /// <summary>
        /// 开启盒子所有监控点
        /// </summary>
        public void StartAllDMonData()
        {
    
    
            //盒子每次掉线后,重新上线后均需要重新开点
            try
            {
    
    
                _fbox.StartAllDataMonitorPointsOnBox(new BoxArgs(boxNo)).Wait();//boxNo为盒子号
            }
            catch (Exception ex)
            {
    
    
                switch (ex.Message)
                    {
    
    
                        // 未登录服务器,请先Restart()
                        case "Box server not found.":; break;
                        // 当前账号下未找到BoxNo序列号的盒子
                        case "Not Found":; break;
                        default:; break;
                    }
            }
        }

        /// <summary>
        /// 获取盒子分组和盒子信息
        /// </summary>
        public void GetBoxGroups()
        {
    
    
            var grpList = _fbox.GetBoxGroups().Result;
            foreach (var grp in grpList)
            {
    
    
                Console.WriteLine(grp.Uid);                 // 盒子分组的Uid
                Console.WriteLine(grp.Name);                // 盒子分组名称
                foreach (var box in grp.Boxes)              // 遍历分组下的盒子集合
                {
    
    
                    Console.WriteLine(box.BoxId);           // 盒子Id
                    Console.WriteLine(box.Alias);           // 盒子名称
                    Console.WriteLine(box.BoxNo);           // 盒子号码
                    Console.WriteLine(box.ConnectionState); // 获取的时候盒子状态, 不能作为实时状态用,也不能一直调用这个接口来作为盒子状态变更,盒子状态变更请使用SignalR实时推送
                    Console.WriteLine(box.NetworkType);     // 网络类型   1:网络, 2:2G, 3:3G (这个不支持),4:Wifi ,5:4G 
                    Console.WriteLine(box.Disabled);        // 盒子是否被禁用
                    Console.WriteLine(box.ApiBaseUrl);      // ApiBaseUrl服务器地址
                    Console.WriteLine(box.SignalrUrl);      // SignalR服务器地址
                    Console.WriteLine(box.Owned);           // 是否为拥有者
                    Console.WriteLine(box.BoxType);         // 盒子类型, 0:标准盒子,1:mini盒子,2:Lite 3:VPN盒子
                }
            }
        }
        //定义方法
    }
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();
                fbox.StartAllDMonData();
                fbox.GetBoxGroups();
                //调用定义的方法
                Console.ReadLine();
            }
        }
    }
}

在创建IFBoxClientManager实例并初始化时,您需要提供一下参数:clientId、clientsecret、username、password、Id server、App server、和Hdata Server。
username、password为FlexManager的账号、密码。
clientId、clientsecret为找销售申请的账号、密码。
Id server、App server、和Hdata Server若公有云的话不变,私有云改为对应地址。

二、具体操作方法

1、引入依赖包

特别说明:
1、此依赖包适用于Visual Studio版本号15.3及以上。
第一步:使用VS2019创建.NET Core Console程序
第二步:引入NuGet依赖包

FBoxClientDriver
FBoxClientDriver.Contract
例如引入FBoxClientDriver包
方式一

在Visual Studio2019命令行中执行如下语句
PM> Install-Package FBoxClientDriver
​```

方式二

在Visual Studio2019中导入项目,在NuGet包库中引入依赖包名,如下图。
在这里插入图片描述

2、初始化

通过配置参数登录服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using FBoxClientDriver;
using FBoxClientDriver.Contract;
using FBoxClientDriver.Impl;

namespace SDKDEMO
{
    
    
    //配置参数
    public class FBoxClientParameters
    {
    
    
        public static string ClientId {
    
     get; set; } = "ClientId";
        public static string ClientSecret {
    
     get; set; } = "ClientSecret";
        public static string UserName {
    
     get; set; } = "UserName";
        public static string Password {
    
     get; set; } = "Password";
        public static string IdServer {
    
     get; set; } = "https://account.flexem.com/core";
        public static string MainServer {
    
     get; set; } = "http://fbox360.com";
        public static string HdataServer {
    
     get; set; } = "http://fbhs1.fbox360.com";
    }

    public class FBoxDemo : IDisposable
    {
    
    
        private readonly IFBoxClientManager _fbox;
        private readonly string boxNo = "300015050009"; // 以这个为例子

        public FBoxDemo()
        {
    
    
            //创建对象并初始化
            var provider =
                new DefaultCredentialProvider(FBoxClientParameters.ClientId, FBoxClientParameters.ClientSecret,
                    FBoxClientParameters.UserName, FBoxClientParameters.Password);
            _fbox = new FBoxClientManager(FBoxClientParameters.IdServer, FBoxClientParameters.MainServer,
                FBoxClientParameters.HdataServer, provider, Guid.NewGuid().ToString("N"), null);
        }

        public void Dispose()
        {
    
    
            _fbox?.Dispose();
        }

       /// <summary>
        /// 启动
        /// </summary>
        public void Start()
        {
    
    
            //初始化SDK,内部建立signalr连接对象,Restart只需全局执行一次。
            _fbox.Restart().Wait();
        }
    }
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                //调用启动方法,内部建立signalr连接对象,Restart只需全局执行一次。
                fbox.Start();

                Console.ReadLine();
            }
        }
    }
}

3、开启指定FBox所有监控点

可开启当前在线FBox的所有监控点数据推送

/// <summary>
/// 开启盒子所有监控点
/// </summary>
public void StartAllDMonData()
{
    
    
    //盒子掉线后,每次上线均需要调此接口
    _fbox.StartAllDataMonitorPointsOnBox(new BoxArgs(boxNo)).Wait();//boxNo为盒子号
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
            }
        }
    }

开启监控点数据推送
可开启指定监控点数据推送

/// <summary>
/// 开启监控点数据推送
/// </summary>
public void StartDmonData()
{
    
    
    // 调接口新增监控点后,需要调此接口才能收到新增点的数据推送
    _fbox.StartDataMonitorPoint(new DataMonitorPointArgs()
    {
    
    
        BoxNo = boxNo,                      //盒子号
        DataMonitorUid = 113470726140747285 //监控点Uid
    });
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartDmonData();//开启监控点
            }
        }
    }

4、盒子状态变更推送

当服务器侦测到FBox发生状态变更,则会推送消息
消息内容为数组
单个对象属性如下表

字段名 类型 参数描述
id string FBox的Id
state int 盒子当前状态,0:未知,1:已连接,2:超时,3:已断开
net int 盒子网络类型1:网络 2:2G,3:3G(目前不支持)4:WIFI,5:4G
rssi int 信号:0~8
vers json对象 FBox固件版本,fcs,fds,floader.
mode int FBox状态0:正常,1:透传中

侦听事件

/// <summary>
/// 启动
/// </summary>
public void Start()
{
    
    
    // 通过参数登录服务器
    _fbox.Restart().Wait();
    //侦听盒子状态变更事件
    _fbox.BoxConnectStateChanged += _fbox_BoxConnectStateChanged;
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
            }
        }
    }
/// <summary>
/// 盒子状态变更函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _fbox_BoxConnectStateChanged(object sender, IList<BoxConnectionStateItem> e)
{
    
    
    foreach (var stateItem in e)
    {
    
    
        Console.WriteLine($"{stateItem.BoxNo},{stateItem.NewState}");
    }
}

5、实时数据推送

前提条件:监控点已经开启,盒子每次掉线后,重新上线后均需要重新开点
当监控点数据发生变化或者开启监控条目时,服务器推送消息。

字段名 类型 参数描述
boxSessionId int 目前可忽略
values json数组 监控点的值集合,单个属性详情见下表
boxUid string FBox的id

value对应属性

字段名 类型 参数描述
id string 监控点条目uid
value string 值,若条目配置小数位则需程序自己转,服务器不做任何中转
status int 如果条目正常,则无此属性1:无数据,2:超时,3:错误,4:Socket异常,5:FDS错误,16:未完成

侦听事件

/// <summary>
/// 启动
/// </summary>
public void Start()
{
    
    
    // 通过参数登录服务器
    _fbox.Restart().Wait();
    //侦听实时数据变更事件
    _fbox.DataMonitorValueChanged += _fbox_DataMonitorValueChanged;
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
            }
        }
    }
/// <summary>
/// 实时数据变更函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _fbox_DataMonitorValueChanged(object sender, IList<DataMonitorValueChangedArgs> e)
{
    
    
    foreach (var dmon in e)
        Console.WriteLine($"dmv:{dmon.Uid}:{dmon.Value},{dmon.Status}");
}

6、获取盒子信息与盒子分组

/// <summary>
/// 获取盒子分组和盒子信息
/// </summary>
public void GetBoxGroups()
{
    
    
    var grpList = _fbox.GetBoxGroups().Result;
    foreach (var grp in grpList)
    {
    
    
        Console.WriteLine(grp.Uid);                 // 盒子分组的Uid
        Console.WriteLine(grp.Name);                // 盒子分组名称
        foreach (var box in grp.Boxes)              // 遍历分组下的盒子集合
        {
    
    
            Console.WriteLine(box.BoxId);           // 盒子Id
            Console.WriteLine(box.Alias);           // 盒子名称
            Console.WriteLine(box.BoxNo);           // 盒子号码
            Console.WriteLine(box.ConnectionState); // 获取的时候盒子状态, 不能作为实时状态用,也不能一直调用这个接口来作为盒子状态变更,盒子状态变更请使用SignalR实时推送
            Console.WriteLine(box.NetworkType);     // 网络类型   1:网络, 2:2G, 3:3G (这个不支持),4:Wifi ,5:4G 
            Console.WriteLine(box.Disabled);        // 盒子是否被禁用
            Console.WriteLine(box.ApiBaseUrl);      // ApiBaseUrl服务器地址
            Console.WriteLine(box.SignalrUrl);      // SignalR服务器地址
            Console.WriteLine(box.Owned);           // 是否为拥有者
            Console.WriteLine(box.BoxType);         // 盒子类型, 0:标准盒子,1:mini盒子,2:Lite 3:VPN盒子
        }
    }
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetBoxGroups();//调用此方法
            }
        }
    }

7、获取盒子监控点分组和监控点条目

/// <summary>
/// 获取盒子监控点分组和监控点条目
/// </summary>
/// <returns></returns>
public IList<DmonItemDtoV2> GetDmonGroups()
{
    
    
    var dmonGrps = _fbox.GetDmonGroupDmonsV2(new BoxArgs(boxNo)).Result;
    foreach (var grp in dmonGrps)
    {
    
    
        Console.WriteLine(grp.Id);          // 监控点分组的Id
        Console.WriteLine(grp.Name);        // 监控点分组的名称
        foreach (var item in grp.Items)     // 遍历当前分组grp下所有的监控点条目
        {
    
    
            Console.WriteLine(item.Id);     //监控点Id
            Console.WriteLine(item.Name);   //监控点名称
            Console.WriteLine(item.DevAlias); //PLC别名
            Console.WriteLine(item.StationNo); //站号
            Console.WriteLine(item.IsDeviceChanged);//设备是否被移除(只有在移除时出现该参数,为true)FBox的连接设备変更后会出现该参数
            Console.WriteLine(item.TaskState);  //条目状态
            Console.WriteLine(item.DeadValue);  //死值区
            Console.WriteLine(item.BitIndex);   //按位索引号
            Console.WriteLine(item.BitIndexEnabled);//是否启用按位索引号
            Console.WriteLine(item.BitStateLabel);//位类型数据标签
            Console.WriteLine(item.CharCount);  //字符个数
            Console.WriteLine(item.DataType);   //数据类型
            Console.WriteLine(item.Encoding);   //编码方式
            Console.WriteLine(item.FractionalDigits);//小数位
            Console.WriteLine(item.GroupId);    //监控点分组
            Console.WriteLine(item.GroupName);  //监控点名称
            Console.WriteLine(item.IntegralDigits);//整数位(目前无作用)
            Console.WriteLine(item.IoWidth);    //寄存器位宽
            Console.WriteLine(item.MainAddress);//主地址
            Console.WriteLine(item.Memo);       //备注
            Console.WriteLine(item.Privilege);  //读写模式
            Console.WriteLine(item.RegId);      //寄存器Id
            Console.WriteLine(item.RegName);    //寄存器名称
            Console.WriteLine(item.StringByteOrder);//字节序
            Console.WriteLine(item.SubAddress); //子地址
            Console.WriteLine(item.SubIndex);   //DB块地址
            Console.WriteLine(item.TrafficSaving);//是否开启省流量模式
            Console.WriteLine(item.Unit);       //单位
            Console.WriteLine(item.ValueTransform);//数据运算
        }
    }
    return dmonGrps.SelectMany(x => x.Items).ToArray();//监控点条目集合
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetDmonGroups();//调用此方法
            }
        }
    }

8、监控点值写入

/// <summary>
/// 监控点写值
/// </summary>
/// <param name="requet"></param>
public void WriteDmonValue(WriteDmonRequest requet)
{
    
    
    _fbox.WriteValue(new DataMonitorWriteValueArgsV2()
    {
    
    
        BoxNo = requet.BoxNo,                     //盒子号
        DataMonitorGroupName = requet.DmonGrpName,//监控点组名称
        DataMonitorName = requet.DmonName,        //监控点条目名称
        Value = requet.Value,                     //条目的值
        Type = WriteValueType.AutoParse //条目值类型,0:和监控点值类型一致,1:十进制,2:字符串,
    }).Wait();
}

public class WriteDmonRequest
{
    
    
    public string BoxNo {
    
     get; set; }
    public string DmonGrpName {
    
     get; set; }
    public string DmonName {
    
     get; set; }
    public object Value {
    
     get; set; }
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.WriteDmonValue();//调用此方法
            }
        }
    }

9、驱动器操作

获取盒子下所有的plc

/// <summary>
/// 获取盒子下的所有PLC
/// </summary>
public void GetPlcs()
{
    
    
    var boxplc = _fbox.GetPlcDeviceV2(new BoxArgs()
    {
    
    
        BoxNo = boxNo                              //盒子号
    }).Result;
    foreach (var plc in boxplc)
    {
    
    
        Console.WriteLine(plc.Alias);               //plc别名
        Console.WriteLine(plc.BaudRate);            //波特率
        Console.WriteLine(plc.BroadcastStationNo);  //广播站号
        Console.WriteLine(plc.Class);//设备类型,0:主设备,1:从设备,2:主从设备(目前不支持)
        Console.WriteLine(plc.DataBits);            //数据位
        Console.WriteLine(plc.DefaultStationNo);    //默认广播站号
        Console.WriteLine(plc.EnableBroadcast);     //使能广播站号
        Console.WriteLine(plc.Interface);//串口接口类型,0:RS232,1:RS485_2,2:RS485_4,85:网络(串口1支持RS232、RS485_2和RS485_4,串口2仅支持RS485_2,串口3仅支持RS232)
        Console.WriteLine(plc.Ip);        //IP地址
        Console.WriteLine(plc.ParityType);//校验位,none:无校验,odd:奇校验,even:偶校验
        Console.WriteLine(plc.PlcAdvancedSettings); //高级设置
        Console.WriteLine(plc.PlcDongleFlag);  //远程停机状态
        Console.WriteLine(plc.PlcId);         //PLCId
        Console.WriteLine(plc.SlaveNo);        //从设备号
        Console.WriteLine(plc.StopBits);     //停止位
        Console.WriteLine(plc.PlcName);      //PLC名称
        Console.WriteLine(plc.Type);       //类型,0:串口,2:以太网
        Console.WriteLine(plc.Port);       //以太网端口号
        Console.WriteLine(plc.PortNo);     //站号
    }
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetPlcs();//调用此方法
            }
        }
    }

下载PLC

/// <summary>
/// 下载PLC
/// </summary>
public void DownloadPlc()
{
    
    
    _fbox.DownLoadPlcsV2(new AddOrUpdatePlcDeviceArgsV2()
    {
    
    
        BoxNo = boxNo,
        PlcList = new List<AddOrUpdatePlcDeviceV2>()
        {
    
    
            //以下为下载一个plc为例
            //注意,本方法下载plc时会覆盖之前的plc,如需多个plc,自行添加
            new AddOrUpdatePlcDeviceV2()
            {
    
    
                PlcId =  305,                       //PLCId
                PlcName = "ABB",                    //PLC名称
                Alias = "ABB AC500_RTU",            //别名
                Type = ServerType.Serial,     //类型,0:串口,2:以太网
                PortNo = 1,                        //编号
                Class = PlcClass.Master,       //设备类型,0:主设备,1:从设备,2:主从设备(目前不支持)
                DefaultStationNo = 1,               //默认站号
                Interface = DeviceInterfaceTypes.Tcp,//串口接口类型,0:RS232,1:RS485_2,2:RS485_4,85:网络(串口1支持RS232、RS485_2和RS485_4,串口2仅支持RS485_2,串口3仅支持RS232)
                BaudRate = 9600,                   //波特率
                Port = 0,                       //网络设备端口号
                DataBits = 8,                     //数据位
                StopBits = 1,                      //停止位
                ParityType = ParityType.None, //校验位,none:无校验,odd:奇校验,even:偶校验
                Ip = "0",                        //IP地址
                EnableBroadcast = false,      //是否启动广播站号
                BroadcastStationNo = 0,        //广播站号
            }
        }
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.DownloadPlc();//调用此方法
            }
        }
    }

10、监控点操作

新增监控点条目

监控点添加完后需要连接SignalR成功后,开启添加的监控点数据推送。

/// <summary>
/// 新增监控点条目
/// </summary>
public void AddDMon()
{
    
    
    _fbox.AddDataMonitorPointV2(new AddDmonsArgsV2()
    {
    
    
        AddDmons = new List<AddDataMonitorDefinitionV2>()
        {
    
    
            new AddDataMonitorDefinitionV2()
            {
    
    
                GroupName =  "fff",//监控点分组名称,和groupId任选一个使用,若使用不存在的监控点分组,则会自动增加该分组
                Name  = "xxxxx",//监控点名称
                DevAlias = "Local",//PLC别名
                StationNo = 1,//站号
                DataType = DataType.Int16,//数据类型,详情见接口文档中附录二
                RegName = "LW",//寄存器名称,和regId、iowidth确定唯一寄存器
                Privilege = PrivilegeType.ReadWrite,//读写权限,2:Write,4:ReadOnly,6:ReadWrite,
                //地址请根据设备的配置进行填写
                MainAddress =  5,//主地址
                SubAddress = 0,//子地址
                SubIndex = 0,//DB块地址
                BitIndexEnabled = false,//是否启用按位索引
                IntegralDigits = 0,//整数位(目前无作用)
                FractionalDigits = 1,//小数位
                Unit = "度",//单位,仅对字类型有效
                TrafficSaving = false,//是否启用省流量模式,true:启用,false:不启用
                BitStateLabel = new BitStateLabel(){
    
    FalseLabel = "关机",TrueLabel = "开机"},//位类型时显示标签,属性ttext:值为1时显示的文本,ftext:值为0时显示的文本
                Memo = "xxx",//备注
                DeadValue = 0,//死区值,数据再±deadValue范围内数据不推送
                //只有在DataType = DataType.String(字符串类型) 时有以下参数
                //Encoding = EncodeType.None,//编码格式,字符串类型使用0:无,非字符串类型使用,1:Unicode,2:Ascii
                //StringByteOrder = StringByteOrder.O12,//字符串字节序,编码为Ascii格式时有效0:倒序,1:正序
                //CharCount = 5, //字符个数
            }
        },
        BoxNo = boxNo,//盒子号
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.AddDMon();//调用此方法
            }
        }
    }

更新监控点条目

监控点添加完后需要连接SignalR成功后,开启监控点数据推送。

/// <summary>
/// 更新监控点条目
/// </summary>
public void UpdateDmon()
{
    
    
    _fbox.UpdateDataMonitorPointV2(new UpdateDmonArgsV2()
    {
    
    
        BoxNo = boxNo,//盒子号
        UpdateDmonList = new List<UpdateDataMonitorDefinitionV2>()
        {
    
    
            new UpdateDataMonitorDefinitionV2()
            {
    
    
                Id = 113470726140747285,//需要更新条目的Id
                GroupName = "fff",//监控点分组名称,和groupId任选一个使用,若使用不存在的监控点分组,则会自动增加该分组
                Name = "ggg",//监控点名称
                DevAlias = "Local",//PLC别名
                StationNo = 1,//站号
                DataType = DataType.Int16,//数据类型,详情见接口文档中附录二
                RegName = "LW",//寄存器名称,和regId、iowidth确定唯一寄存器
                //地址请根据设备的配置进行填写
                MainAddress = 9,//主地址
                SubAddress = 0,//子地址
                SubIndex = 0,//DB块地址
                IntegralDigits = 0,//整数位(目前无作用)
                FractionalDigits = 1,//小数位
                Unit = "度",//单位
                Privilege = PrivilegeType.ReadOnly,//读写权限,2:Write,4:ReadOnly,6:ReadWrite,
                TrafficSaving = true,//是否启用省流量模式,true:启用,false:不启用
                DeadValue = 15,//死区值,数据再±deadValue范围内数据不推送
                BitStateLabel =  new BitStateLabel(),//位类型时显示标签,属性ttext:值为1时显示的文本,ftext:值为0时显示的文本
                Memo = "ggg",//备注
                Encoding = EncodeType.None//编码格式,字符串类型使用0:无,非字符串类型使用,1:Unicode,2:Ascii
            }
        }
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.UpdateDmon();//调用此方法
            }
        }
    }
删除监控点条目
/// <summary>
/// 删除监控点条目
/// </summary>
public void RemoveDmon()
{
    
    
    List<long> ids = new List<long> {
    
     113470815205744205 };
    _fbox.RemoveDataMonitorPointV2(new RemoveDataMonDefArgsV2()
    {
    
    
        BoxNo = boxNo, //盒子号
        Ids = ids      //需要删除的监控点条目Id集合
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.RemoveDmon();//调用此方法
            }
        }
    }

11、报警操作

获取盒子底下所有的报警条目

/// <summary>
/// 获取盒子底下所有的报警条目
/// </summary>
/// <returns></returns>
public IList<AlarmDefintitionDtoV2> GetAlarmItems()
{
    
    
    var allitems = _fbox.GetAllAlarmDefinitionsV2(new BoxArgs()
    {
    
    
        BoxNo = boxNo
    }).Result;
    foreach (var items in allitems)
    {
    
    
        Console.WriteLine(items.TaskState);    //条目状态
        Console.WriteLine(items.AlarmGroup);   //报警分组
        Console.WriteLine(items.AlarmMessage); //报警信息
        Console.WriteLine(items.Code);         //报警条目编码
        Console.WriteLine(items.Condition1);   //报警条件一
        Console.WriteLine(items.ConditionCombineMethod);//条件组合
        Console.WriteLine(items.Id);            //报警条目Id
        Console.WriteLine(items.IsDeviceChanged);//设备是否已经变更
        Console.WriteLine(items.Memo);          //备注
        Console.WriteLine(items.Name);          //报警条目名称
        Console.WriteLine(items.Operand1);      操作数,若选择Bit数据类型,操作数0为OFF,1为ON
        Console.WriteLine(items.Condition2);    //报警条件二
        Console.WriteLine(items.Operand2);      //操作数二
    }
    return allitems;
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetAlarmItems();//调用此方法
            }
        }
    }

获取报警历史记录条目

/// <summary>
/// 获取报警历史记录
/// </summary>
public void GetAlarmHistory()
{
    
    
    var hdata = _fbox.GetAlarmEvents(new AlarmEventQuery()
    {
    
    
        BeginTime = DateTime.Parse("2018-4-5"), //开始时间 long型的utc时间戳unix epoch
        BoxNo = boxNo,                          //盒子号
        EndTime = DateTime.Parse("2018-4-24"),  //结束时间 long型的utc时间戳unix epoch
        Limit = 500,                            //获取条数限制,结果条数限制 负值为向前查询,建议使用500.
        Name = "313265"                         //报警条目的编码,若全查则无需该参数
    }).Result;
    foreach (var data in hdata)
    {
    
    
        Console.WriteLine(data.Action);         //类型
        Console.WriteLine(data.AlarmId);        //报警条目Id
        Console.WriteLine(data.Code);           //报警条目编码
        Console.WriteLine(data.Message);        //报警信息
        Console.WriteLine(data.Value);          //监控点值
        Console.WriteLine(data.TimestampUnixEpoch); //时间戳
    }
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetAlarmHistory();//调用此方法
            }
        }
    }

新增报警条目

/// <summary>
/// 新增报警条目
/// </summary>
public void AddAlarm()
{
    
    
    _fbox.AddAlarmDefinitionV2(new AddAlarmDefArgsV2()
    {
    
    
        AddAlarms = new List<AddAlarmDefinitionV2>()
        {
    
    
            new AddAlarmDefinitionV2()
            {
    
    
                Name = "报警名称",        // 新增报警条目名称是唯一的,不可同名
                DevAlias = "Modbus_TCP", //设备驱动别名
                StationNo = 1,          //PLC通讯站号
                DataType = DataType.Bit, //数据类型,详情见接口文档中附录二
                RegName = "4X_bit",    //寄存器名称,和regId、iowidth确定唯一寄存器
                //地址请根据报警条目需要检测的监控点配置
                MainAddress = 8, //主地址
                SubAddress = 0,//子地址
                SubIndex = 0,//DB块地址
                AlarmMessage = "XXXX",  //报警信息
                GroupName = "报警分组", //报警点分组名称或使用GroupId报警分组Id,优先名称
                Memo = "",             //备注
                //以下为报警条件
                Condition1 = AlarmConditionType.Eq,//触发报警条件类型,报警条件一,0:不等于,1:等于,2:大于,3:大于等于,4:小于,5:小于等于
                Operand1 = 80,  //条件值
                ConditionCombineMethod = AlarmConditionCombineMethod.And, //条件联合,None:无,And:与,Or:或
                Condition2 = AlarmConditionType.Eq,//触发报警条件类型,报警条件一,0:不等于,1:等于,2:大于,3:大于等于,4:小于,5:小于等于
                Operand2 = 90 //条件值
            }
        },
        BoxNo = boxNo     //新增报警条目的盒子号
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.AddAlarm();//调用此方法
            }
        }
    }

更新报警条目

/// <summary>
/// 更新报警条目
/// </summary>
public void UpdateAlarm()
{
    
    
    _fbox.UpdateAlarmDefinitionV2(new UpdateAlarmDefArgsV2()
    {
    
    
        BoxNo = boxNo,//报警条目的盒子号
        UpdateAlarms = new List<UpdateAlarmDefinitionV2>()
        {
    
    
            new UpdateAlarmDefinitionV2()
            {
    
    
                Id = 113522543645056649,//报警条目的Id
                Name = "修改了", //报警条目名称 
                DevAlias = "Modbus_TCP",//设备驱动别名
                StationNo = 1, //PLC通讯站号
                DataType = DataType.Int16,//数据类型,详情见接口文档中附录二
                RegName = "4X",//寄存器名称,和regId、iowidth确定唯一寄存器
                //地址请根据报警条目需要检测的监控点配置
                MainAddress = 2, //主地址
                SubAddress = 0,//子地址
                SubIndex = 0,//DB块地址
                GroupName = "报警分组",//报警分组名称,与groupId使用一个即可
                //以下为报警条件
                Condition1 = AlarmConditionType.Lt,//触发报警条件类型,报警条件一,0:不等于,1:等于,2:大于,3:大于等于,4:小于,5:小于等于
                Operand1 = 12,//条件值一,若选择Bit数据类型,操作数0为OFF,1为ON
                ConditionCombineMethod = AlarmConditionCombineMethod.And, //条件联合,None:无,And:与,Or:或
                Condition2 = AlarmConditionType.Eq,//触发报警条件类型,报警条件二,0:不等于,1:等于,2:大于,3:大于等于,4:小于,5:小于等于
                Operand2 = 90 //条件值二
            }
        }
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.UpdateAlarm();//调用此方法
            }
        }
    }

删除报警条目

/// <summary>
/// 删除报警条目
/// </summary>
public void RemoveAlarm()
{
    
    
    var ids = new List<long>(){
    
     110424333146494353};
    _fbox.RemoveAlarmDefinitionV2(new RemoveAlarmDefArgsV2()
    {
    
    
        BoxNo = boxNo,      //盒子号
        Ids = ids           //删除的报警条目UId
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.RemoveAlarm();//调用此方法
            }
        }
    }

12、历史操作

获取历史记录多通道数据

/// <summary>
/// 获取历史记录多通道数据
/// </summary>
public IList<ByRowHistoryDataRow> GetHdataHistory()
{
    
    
    var hdata =  _fbox.GetByRowHistoryData(new GetHistoryDataArgs()
    {
    
    
        BoxNo = boxNo,                                //盒子号
        StartTime = DateTime.Parse("2018-06-06 08:58:32"),       //起始时间
        EndTime = DateTime.Parse("2018-06-07 08:58:32"),        //结束时间
        Limit = 500,                                 //最大获取数据条数
        TimeRange = TimeRangeTypes.BeginOpenEndOpen, //区间类型,BeginCloseEndClose:全毕区间,BeginCloseEndOpen:左闭右开,BeginOpenEndClose:左开右闭,BeginOpenEndOpen:全开区间
        HdataItemName = "XX",                        //历史数据条目名称
        HdataChannelNames = new List<string>() {
    
     "11", "22"}//通道名称
    }).Result;
    foreach (var d in hdata.Rows)
    {
    
    
        Console.WriteLine(d.Time); // 历史数据条目的采集时间
        Console.WriteLine(d.Values[0]); // 对应通道名称集合中的第一个元素
        Console.WriteLine(d.Values[1]); // 对应通道名称集合中的第二个元素
    }
    return hdata.Rows;
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetHdataHistory();//调用此方法
            }
        }
    }

获取历史记录条目

/// <summary>
/// 获取历史记录条目
/// </summary>
public void GetHdataList()
{
    
    
    var itemlist =  _fbox.GetHdataItems(new BoxArgs()
    {
    
    
        BoxNo = boxNo                                       //盒子号
    }).Result;
    foreach (var items in itemlist)
    {
    
    
        Console.WriteLine(items.BoxId);                     //盒子Id
        foreach (var channels in items.Channels)
        {
    
    
            Console.WriteLine(channels.Uid);                //通道Id
            Console.WriteLine(channels.HasSubAddress);      //寄存器是否有子地址
            Console.WriteLine(channels.HasSubIndex);        //寄存器是否有DB块地址
            Console.WriteLine(channels.DataType);           //数据类型,详情见接口文档中附录二
            Console.WriteLine(channels.MainAddress);        //主地址
            Console.WriteLine(channels.RegName);            //寄存器名称
            Console.WriteLine(channels.RegId);              //寄存器Id
            Console.WriteLine(channels.IoWidth);            //寄存器位宽
            Console.WriteLine(channels.StationNo);          //站号
            Console.WriteLine(channels.SubAddress);         //子地址
            Console.WriteLine(channels.DevAlias);           //PLC别名
            Console.WriteLine(channels.SubIndex);           //DB块地址
        }
        Console.WriteLine(items.Name);                      //名称
        Console.WriteLine(items.RecordingPeriod);           //采集周期
        Console.WriteLine(items.Uid);                       //主键
        Console.WriteLine(items.IsControl);                 //是否使用使能
    }
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.GetHdataList();//调用此方法
            }
        }
    }

新增历史记录条目

/// <summary>
/// 新增历史记录多通道
/// </summary>
public void AddHdata()
{
    
    
    _fbox.AddHdataItems(new AddHdataItemArgs()
    {
    
    
        BoxNo = boxNo,                          //盒子号
        HdataItems = new List<AddHdataItemDto>()
        {
    
    
            //以下为增加一个通道为例,增加多个通道自行增加
                    new AddHdataChannelsDto()
                    {
    
    
                        ChannelName = "xxx",    //通道名称
                        AddressDescription = "LW",//地址描述
                        StationNo = 2,          //站号
                        DataType = DataType.Bcd16,//数据类型,详情见接口文档中附录二
                        DevAlias = "Modbus_TCP",  //PLC别名
                        RegName = "4X",        //寄存器名称,与regId,iowidth确认唯一寄存器
                        //请根据设备的配置填写
                        MainAddress = 5,        //主地址
                        SubAddress = 0,         //子地址
                        SubIndex = 0,           //DB块地址
                        BitIndex = 0,           //按位索引号
                        BitIndexEnabled = false,//是否启用按位索引 
                        FractionalDigits = 1,   //通道小数位
                    }
                },
                IsControl = true, //是否使能控制
                //当使能控制为true时,填写以下使能参数
                ControlOptions = new HDataControlOptionsV2()//使能参数
                {
    
    
                    ControlType = HControlType.OFF,//使能配置,0:OFF,1:ON
                    DataType = DataType.Bit,    //数据类型,详情见接口文档中附录二
                    DevAlias = "Modbus_TCP",    //PLC别名
                    StationNo = 2,              //站号
                    RegName = "4X_bit",         //寄存器名称,和regId、iowidth确定唯一寄存器
                    //请根据设备的配置填写
                    MainAddress = 2,            //主地址
                    SubAddress = 3,             //子地址
                    AddressDescription = "LW",  //地址描述
                    BitIndex = 2,               //按位索引号
                    BitIndexEnabled = false     //是否启用按位索引
                }
            }
        }
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.AddHdata();//调用此方法
            }
        }
    }

更新历史记录条目

/// <summary>
/// 更新历史记录多通道
/// </summary>
public void UpdateHdata()
{
    
    
    _fbox.UpdateHdataItems(new UpdateHdataItemArgs()
    {
    
    
        BoxNo = boxNo,
        HdataItems = new List<UpdateHdataItemDto>()
        {
    
    
            //以下为更新一个通道为例
                    new UpdateHdataChannelsDto()
                    {
    
    
                        Uid = 97427676249298676, //通道Uid
                        ChannelName = "15",//通道名称
                        DevAlias = "ABB AC500_RTU",//PLC别名
                        StationNo = 2,//站号
                        DataType =   DataType.Int16,//数据类型,详情见接口文档中附录二
                        RegName = "4X",//寄存器名称,与regId,iowidth确认唯一寄存器
                        //请根据设备的配置进行填写
                        MainAddress = 7,//主地址
                        SubAddress = 0,//子地址
                        SubIndex = 0,//索引地址
                        Unit = "°",//单位
                        IntegralDigits = 0,//整数位
                        FractionalDigits = 2//小数位
                    }
                },
                IsControl = true,   //是否启用使能配置
                //当启用使能配置时,请配置使能参数
                ControlOptions = new HDataControlOptionsV2()//使能参数
                {
    
    
                    ControlType = HControlType.OFF,//使能状态,0:OFF,1:ON
                    DataType = DataType.Bit,  //数据类型,详情见接口文档中附录二
                    DevAlias = "ABB AC500_RTU",   //PLC别名
                    StationNo = 2,              //站号
                    RegName = "0X",             //寄存器名称与regId,iowidth确认唯一寄存器
                    //请根据设备的配置进行填写
                    MainAddress = 2,            //主地址
                    SubAddress = 0,             //子地址
                    AddressDescription = "ABB",  //地址描述
                    BitIndex = 0,               //按位索引号
                    BitIndexEnabled = false     //是否启用按位索引
                },
            }
        }
    });
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.UpdateHdata();//调用此方法
            }
        }
    }
删除历史记录条目
/// <summary>
/// 删除历史记录条目
/// </summary>
public void RemoveHdata()
{
    
    
    _fbox.RemoveHdataItem(new RemoveHdataItemArgs()
    {
    
    
        BoxNo = boxNo,                                  //盒子号
        Ids = new List<long>() {
    
     85289974828733605 }    //历史记录Id集合
    }).Wait();
}
//在Program,Main函数中调用
class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            using (var fbox = new FBoxDemo())
            {
    
    
                fbox.Start();  //启动
                fbox.StartAllDMonData();//开启FBox所有监控点
                fbox.RemoveHdata();//调用此方法
            }
        }
    }

总结

以上就是今天要讲的内容,本文仅仅简单介绍了基于FlexManager的Visual Studio应用开发,而FlexManager提供了大量能使我们自己使用云数据创建客户端应用的方式方法,同学们可以多深入了解一下。下一篇将具体讲述在FlexManager的基础上进行数据云间中转的实际操作细节,欢迎同学们进一步的来学习。

猜你喜欢

转载自blog.csdn.net/weixin_41729677/article/details/126561762