异构接入底层网关实现

   该异构接入网关底层需要实现对多种接口传感设备数据的读入(例如DI/DO类设备,Modbus接口的传感器设备,工业无线网ISA100.11a传输的数据),并能将数据存储,上层网关可定时取出下层网关数据库中数据,并封装成工厂Mesh系统所需数据样式,与工厂Mesh系统交互,其网关下层模型主要参考了EdgeX Foundry结构的下层模块实现,并进行了一定程度的简化,EdgeX Foundry的结构如下:


    其中Device service层主要负责下层设备的接入及对应数据获取,Core Service主要对设备类型信息及设备数据进行存储,Supporting Service主要负责系统运行,Export Service主要负责对对外服务。

    我们下层网关主要参考下两层实现:即能对底层多型设备进行接入并获取数据,及将设备类型数据及设备感知数据写入数据库。

1.下层网关继承体系

1.1 数据库类继承示意图


因为下层网关要对获得的数据进行暂时存储,因此需要在本地建立mysql数据库,此外,由于DIDO类数据、温湿度类数据及PM值类数据其本身数据量及数据属性不同,因此,其数据应该分别存储在不同的数据表中,因此需要建立各自的读、写、该、删数据库表的方法。

1.2 设备类继承示意图


Device_base(设备基类)主要封装设备最基础的性质,如设备ID设备类型设备地址(设备地址强制性与设备ID为同一值,设备地址为传感器设备地址寄存器中的值,其范围是0x01~0xff,在执行串口读写命令时,命令的第一个字节均为设备地址)。

Device_modbus(modbus设备类)主要封装了设备路径(存储对应设备在linux下的路径,char *型,如 "/dev/ttyUSB0")读命令(char*型字符串),以及用于计算CRC循环校验的方法(modbus设备读串口命令后面两字节主要前面部分的CRC循环校验值)。

Device_modbus_th继承自Device_modbus类,封装了sqlcon_modbus_th对象指针(用于获取温湿度值后插入对应数据库温湿度表),double型温度double型湿度,及获取温度、湿度值辅助函数

Device_modbus_pm继承自Device_modbus类,封装了sqlcon_modbus_pm对象指针(用于获取pm值后插入对应数据库pm值表),unsigned int型PM2.5值unsigned int型PM10值,及获取PM值辅助函数

Device_modbus_dido继承自Device_modbus类,封装了sqlcon_modbus_dido对象指针(用于获取dido值后插入对应数据库dido表),8个unsigned int di值(unsigned int型,不是0就是1,表示联通或者断开)。

2. 数据库操作类具体设计

2.1 sqlcon_base设计

 /*编译时加  `mysql_config --cflags --libs`   */
class sqlcon_base
{
protected:
    MYSQL * conn;    //MYSQL连接对象
    char *host;      //主机地址
    char *user;    //数据库用户名
    char *pd;     //数据库用户密码
    char *dbname;     //数据库名字
public:
    sqlcon_base();    //默认构造函数,直接传入自己数据库相关信息
    sqlcon_base(char *ht, char *usr, char *pad, char *name);    //全参数构造函数,可以传入自己需要的数据库参数
    virtual ~sqlcon_base();
    MYSQL * get_conn();
    void connect_sql();
}; 

2.2 sqlcon_dido设计

class sqlcon_dido:public sqlcon_base
{
private:
    char *table_name;//相比起数据库基类,只添加了一个table_name(该名字用于标识数据库中dido数据表)
public:
    sqlcon_dido();
    sqlcon_dido(char * ht,char * usr,char * pad,char * name,char *tbname);
    sqlcon_dido(char *tbname);
    ~sqlcon_dido();
    /*search函数可以重载以满足不同搜索条件*/
    didodata search_sql(unsigned int id);
    void insert_sql(didodata * data);    //此函数用于插入dido表,didodata类型数据定义在value_type.h里
    void update_sql(unsigned int id, didodata data); //此函数用于更新dido表中id为传入id的数据
    void delete_sql(unsigned int id);  //删除表中数据
};

2.3 sqlcon_modbus_th设计

class sqlcon_modbus_th:public sqlcon_base
{
private:
    char *table_name;  //数据库中存储温湿度数据的表名
public:
    sqlcon_modbus_th();
    sqlcon_modbus_th(char * ht,char * usr,char * pad,char * name,char *tbname);
    sqlcon_modbus_th(char *tbname);
    ~sqlcon_modbus_th();
    /*search函数要考虑多种搜索条件,例如只给id,查温度,湿度,或者查温度或者湿度的情况*/
    /*此时暂时写根据id查温湿度的情形*/
    modbusdata search_sql(unsigned int id);
    void insert_sql(modbusdata *data);  //此函数用于插入温湿度表,modbusdata类型数据定义在value_type.h里
    void update_sql(unsigned int id,double temperature,double humidity);  //依据传入设备id号更新设备在数据库中数据
    void delete_sql(unsigned int id);  //依据传入id删除表中数据
};

sqlcon_modbus_pm设计与sqlcon_modbus_th极其相似,就不在这里详细展开。

3. 设备类具体设计

3.1 device_base类设计

class Base_device
{
protected:
    unsigned int deviceID;   //设备id
    device_type deviceType;    //设备类型,定义在value_type.h头文件中
    unsigned int deviceAddress;    //设备地址
public:
    Base_device();
    Base_device(unsigned int id);
    virtual ~Base_device();
    unsigned int get_deviceID();
    void set_deviceID(unsigned int id);
    device_type get_deviceType();
    void set_deviceType(device_type type);
    unsigned int get_deviceAddress();
    virtual void run()=0;
    virtual void insert()=0;
    virtual void update()=0;
};
设备基类之所以要设置底下三个虚函数,主要是为了实现动态多态,在第四节设备管理器类里,设备管理器使用vector存储各个设备指针,因此只能存储设备基类指针(Base * ptr=new Derived(),从而实现各个继承类的方法)。


3.2 device_modbus类设计

device_modbus类继承自device_base类,其主要作用是封装了使用modbus通信协议的传感器设备公共数据成员公用方法

class Modbus_device:public Base_device
{
protected:
    char * device_path;  //设备地址,即设备在linux系统下位置,如"/dev/ttyUSB0"
    unsigned char *rd_cmd;   //读命令,char型字符串
    /*用于计算crc循环函数*/
    void InvertUint8(unsigned char *dBuf, unsigned char *srcBuf);
    void InvertUint16(unsigned short *dBuf, unsigned short *srcBuf);
    unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen);
    virtual void set_rd_cmd(unsigned char *rd_cmd,unsigned int id);  //虚函数,具体实现在继承类里,用于根据设备地址计算rd_cmd的数据
public:
    Modbus_device();
    virtual ~Modbus_device();
};

3.3 device_modbus_dido类设计

     device_modbus_dido类继承自device_modbus类,主要功能是获取dido状态并更新对应数据库表

class Modbus_device_dido:public Modbus_device
{
private:
    unsigned int di1;   //一个dido传感设备可同时监听八路dido信号
    unsigned int di2;
    unsigned int di3;
    unsigned int di4;
    unsigned int di5;
    unsigned int di6;
    unsigned int di7;
    unsigned int di8;
    sqlcon_dido * ptr_sqlcon_dido;    //sqlcon_dido对象指针,用于device_modbus_dido设备类对象在获取到数据后,更新对应的数据库
    /*用于计算crc循环函数*/
    void set_rd_cmd(unsigned char *rd_cmd,unsigned int id);

public:
    Modbus_device_dido();
    Modbus_device_dido(unsigned int id,char * path);
    ~Modbus_device_dido();
    didodata get_dido(char a);

    /*用于封装sqlcon_dido的insert与update方法*/
    void update();
    void insert();
    /*打印dido接口数据的函数*/
    void show_dido();
    void run();//具体的读写串口函数,每执行一次,会更新di1~di8的值,
};

3.4 device_modbus_th类设计

    device_modbus_th类继承自device_modbus类,其主要作用是获取温湿度值,并写入对应的数据库表

class Modbus_device_th:public Modbus_device
{
private:
    double temperature;  //温度值
    double humidity;    //湿度值
    sqlcon_modbus_th * ptr_sqlcon_modbus;   //sqlcon_modbus_th指针,用于device_modbus_th设备获取温湿度值以后写入对应数据库表
    bool is_fullone(char a);//此函数用于温度计算(辅助函数)
    double func(int *a,int n);//用于温度计算(辅助函数)
    void set_rd_cmd(unsigned char *rd_cmd,unsigned int id);
public:
    Modbus_device_th();
    Modbus_device_th(unsigned int id,char *path);
    ~Modbus_device_th();
    double get_temperature(char a,char b);
    double get_humidity(char a,char b);

    /*用于封装sqlcon_modbus的insert与update方法*/
    void update();
    void insert();
    /*打印温度值与湿度值的函数*/
    void show_temperature();
    void show_humidity();
    void run();
//具体的读写串口函数,每执行一次,会更新temperature与humidity的值
};device_modbus_pm与device_modbus_th设计几乎相同,就不在此赘述。

4. 设备管理器具体设计

device_manager:

    device_manager用于管理已接入的设备(读取设备信息表),定时获取对应设备数据,并更新对应设备传感信息数据库,

设备信息表主要含以下几项(id,type,location,path,其中type是设备类型,location为设备安放位置,path为设备在linux环境下设备路径)。

class device_manager
{
private:
    sqlcon_add_device * addDevice_ptr;   //添加设备类,用以将设备加进设备信息表中
    unordered_map<int,int> find_Device;   //标记设备是否在device_list中
    vector<Base_device *> device_list;   //所有设备的链表指针
    Base_device * chooseToCreate(MYSQL_ROW row);//依据查询设备数据库得到的设备类型,执行对应设备的构造函数
public:
    device_manager();
    explicit device_manager(char * tbname);
    ~device_manager();
    void addDeviceToList();//查询设备数据库,并将新设备更新到设备列表中
    void run();//run里首先执行上面的addDeviceToList函数(更新设备vector),然后遍历vector(执行对应的insert(新设备)或者update(已添加过的设备))
};

调用顺序:(1)主函数创建device_manager(传入设备信息表)->run()

                (2)(1)中run 调用addDeviceToList更新设备List

                (3)遍历设备LIst,调用Base* ptr->insert() 或者update()方法

                (4) insert 和update方法先调用自身设备类的run()方法更新设备成员变量(即dido值,温湿度值),再调用对应的

                    数据库指针(如sqlcon_modbus_th)更改设备传感器值数据库。

                (5)while循环,重新执行(2)~(4)步骤

5. 小结

     该网关初步设计便是上述的样子,可能以后会对其继续改进,满足后续增加的要求,项目完整代码地址如下:

       git@github.com:longjialin93528/YanXiang.git

    欢迎查阅。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值