首页 > 其他分享 >网关点表&&全局点表json文件使用(拓展性实现方法)

网关点表&&全局点表json文件使用(拓展性实现方法)

时间:2024-10-25 08:51:58浏览次数:3  
标签:点表 网关 name type json key address query config

全局点表

点表作用

每一个网关中都会有配置点表,它会在里面写入一些网关运行过程中所需要的配置项,比如连接的服务器地址、当前固件版本号等。而点表最重要的作用就是定义网关需要采集或者处理的设备点抽象,实际开发中我们会将每个需要关注的终端设备抽象成一个具体的数据点,这个点里通常包含key:代表终端设备的唯一键值name:当前点代表的设备type:当前设备的数据类型,比如温度传感器是浮点型的,灯是bool类型的,其它的成员可能略有不同,比如modbus设备会有具体的modbus协议地址。点表不是一成不变的,因为网关是个通用品,很可能对下采集的设备会发生改变。所以程序设计时候必须根据实际情况来,直接在程序中写死需要处理的数据点不具备扩展性。如果不考虑扩展性,把设备定死也是可以做的,根据项目自行决定即可。

点表使用

真实物联网场景中,点表通过客户端界面(上位机或者web页面)编辑,生成json文件后下发给设备,设备解析使用。下发过程详见网关开发指导--设备搜索响应进程,注意网关设备端进程在调试过程中,可以先固定一个目录:比如/mnt/config,把点表固定放到此目录,所有进程共享。在搜索响应进程获取点表之前,其它模块调试时候可以先提前放一个到目录使用,最后再联调即可。

{
	"version": "v1.0", //协议版本,方便后续升级
	"report": { //设备上报属性
		"type": 1, //0-不上报,客户端主动采集;1-变化上报,即连续2次值不相等;2-周期上报
		"period": 5 //上报周期时间,单位秒,仅在type=2时有效
	},
	"mqtt_server": { //mqtt服务器配置
		"addr": "192.168.x.x",
		"port": 1883
	},
	"mb_dev": { //modbus设备地址配置
		"addr": "192.168.x.x",
		"port": 502
	},
	"mb_app": {  //手机IP地址
		"addr": "192.168.xx.xx",
		"port": 8887
	},  
  "stm32":{
    "data": [{        
				"key": 301, //第一个点比较特殊,根据自己组实际传感器的实际情况来,可以修改
				"name": "sensor", //数据点名称(确保单个设备内的唯一性)
				"type": 3 //数据点值的类型,1:bool类型 2:int型  3:float型
			},
			{
				"key": 302,
				"name": "bat",  //电池电量
				"type": 3
			},
			{
				"key": 303,
				"name": "light",  //电灯
				"type": 1
			}
		]
  },
	"m0": {
		"data": [{
				"key": 1, //数据点唯一标识(确保数据点表内的唯一性)
				"name": "temperature", //数据点名称(确保单个设备内的唯一性)
				"type": 3 //数据点值的类型,1:bool类型 2:int型  3:float型
			},
			{
				"key": 2,
				"name": "humidity",
				"type": 3
			},
			{
				"key": 3,
				"name": "ill",
				"type": 2
			},
			{
				"key": 4,
				"name": "light",
				"type": 1
			},
			{
				"key": 5,
				"name": "alarm",
				"type": 1
			},
			{
				"key": 6,
				"name": "fan",
				"type": 2
			}
		]
	},
	"modbus": {
		"data": [{
				"key": 101, //数据点唯一标识(确保数据点表内的唯一性)
				"name": "temperature", //数据点名称(确保单个设备内的唯一性)
				"addr": 30001, //modbus地址,根据设备类型选择,温度传感器是只读的输入寄存器
				"type": 3 //数据点值的类型,1:bool类型 2:int型  3:float型
			},
			{
				"key": 102,
				"name": "humidity",
				"addr": 30003, //湿度传感器是只读的输入寄存器
				"type": 3
			},
			{
				"key": 103,
				"name": "air-switch",
				"addr": 1, //空调开关是线圈寄存器
				"type": 1
			},
			{
				"key": 104,
				"name": "air-temp",
				"addr": 40001, //空调温度控制,保持寄存器
				"type": 3
			},
			{
				"key": 105,
				"name": "light",
				"addr": 2, //灯控,线圈寄存器
				"type": 1
			}
		]
	},
	"mbapp": {
		"data": [{
				"key": 201, //数据点唯一标识(确保数据点表内的唯一性)
				"name": "ill", //数据点名称(确保单个设备内的唯一性)
				"addr": 40001, //modbus地址,根据设备类型选择,温度传感器是只读的输入寄存器
				"type": 2 //数据点值的类型,1:bool类型 2:int型  3:float型
			},
			{
				"key": 202,
				"name": "x",
				"addr": 40002, //湿度传感器是只读的输入寄存器
				"type": 3
			},
			{
				"key": 203,
				"name": "y",
				"addr": 40003, //空调开关是线圈寄存器
				"type": 3
			},
			{
				"key": 204,
				"name": "z",
				"addr": 40004, //空调温度控制,保持寄存器
				"type": 3
			},
			{
				"key": 205,
				"name": "light",
				"addr": 1, //灯控,线圈寄存器
				"type": 1
			},
			{
				"key": 206,
				"name": "alarm",
				"addr": 2, //报警
				"type": 1
			}
		]
	}
}


下文拓展性的实现方法,如果不使用python的话,可以直接看实现方法二:基于QT实现


拓展性实现

一、数据库存储配置点表

数据库选型与设计
- 可以选择关系型数据库(如 MySQL、PostgreSQL)或者非关系型数据库(如 MongoDB)来存储配置点表。如果选择关系型数据库,可以创建一个名为`gateway_configuration`的表,包含字段如`id`(自增主键)、`key`(终端设备唯一键值)、`name`(设备名称)、`type`(数据类型)、`server_address`(连接的服务器地址)、`firmware_version`(固件版本号)等。对于有特殊协议要求的设备,如 Modbus 设备,可以添加`modbus_address`字段。
- 例如,在 MySQL 中创建表的 SQL 语句如下:
     CREATE TABLE gateway_configuration (
       id INT AUTO_INCREMENT PRIMARY KEY,
       key VARCHAR(255) NOT NULL,
       name VARCHAR(255),
       type VARCHAR(50),
       server_address VARCHAR(255),
       firmware_version VARCHAR(50),
       modbus_address VARCHAR(50)
     );  
数据访问层实现
- 设计数据访问层(Data Access Layer,DAL)来操作数据库。可以使用编程语言对应的数据库驱动或者 ORM(Object - Relational Mapping)框架。例如,在 Python 中使用 SQLAlchemy,定义一个`GatewayConfiguration`类来映射数据库表。
   from sqlalchemy import Column, String, Integer
   from sqlalchemy.ext.declarative import declarative_base

   Base = declarative_base()

   class GatewayConfiguration(Base):
       __tablename__ = 'gateway_configuration'
       id = Column(Integer, primary_key=True)
       key = Column(String)
       name = Column(String)
       type = Column(String)
       server_address = Column(String)
       firmware_version = Column(String)
       modbus_address = Column(String)
  • 然后可以通过这个类来进行数据的增删改查操作,如添加新的配置点:
   from sqlalchemy import create_engine
   from sqlalchemy.orm import sessionmaker

   engine = create_engine('mysql+pymysql://user:password@localhost:3306/database_name')
   Session = sessionmaker(bind=engine)
   session = Session()

   new_config = GatewayConfiguration(key='device1', name='Temperature Sensor', type='float', server_address='192.168.1.100', firmware_version='1.0', modbus_address='')
   session.add(new_config)
   session.commit()
动态加载配置
- 在网关启动时,通过数据访问层从数据库中读取配置点表的数据,并将其加载到内存中的数据结构(如字典或列表)中。例如,在 Python 中:
   def load_configuration():
       configuration_list = []
       configs = session.query(GatewayConfiguration).all()
       for config in configs:
           config_dict = {
               'key': config.key,
               'name': config.name,
               'type': config.type,
               'server_address': config.server_address,
               'firmware_version': config.firmware_version,
               'modbus_address': config.modbus_address
           }
           configuration_list.append(config_dict)
       return configuration_list

   configuration_data = load_configuration()  
  • 这样,当采集设备发生变化时,只需要修改数据库中的记录,网关下次启动或重新加载配置时就可以获取新的配置信息。

二、配置文件存储配置点表(如 JSON 或 XML 格式)

配置文件格式选择与设计
- **JSON 格式**:JSON 文件易于阅读和编写,也方便在不同编程语言之间进行解析。例如,创建一个`gateway_configuration.json`文件,其结构如下:
   {
       "configurations": [
           {
               "key": "device1",
               "name": "Temperature Sensor",
               "type": "float",
               "server_address": "192.168.1.100",
               "firmware_version": "1.0",
               "modbus_address": ""
           },
           {
               "key": "device2",
               "name": "Light Switch",
               "type": "bool",
               "server_address": "192.168.1.100",
               "firmware_version": "1.0",
               "modbus_address": ""
           }
       ]
   }
  • XML 格式:XML 格式更加灵活,支持复杂的结构和验证机制。例如,一个类似的gateway_configuration.xml文件可以这样设计:
   <?xml version="1.0" encoding="UTF-8"?>
   <gateway_configurations>
       <configuration>
           <key>device1</key>
           <name>Temperature Sensor</name>
           <type>float</type>
           <server_address>192.168.1.100</server_address>
           <firmware_version>1.0</firmware_version>
           <modbus_address></modbus_address>
       </configuration>
       <configuration>
           <key>device2</key>
           <name>Light Switch</name>
           <type>bool</type>
           <server_address>192.168.1.100</server_address>
           <firmware_version>1.0</firmware_version>
           <modbus_address></modbus_address>
       </configuration>
   </gateway_configurations>
配置文件解析与加载
- **JSON 解析(以 Python 为例)**:
   import json

   with open('gateway_configuration.json', 'r') as file:
       configuration_data = json.load(file)['configurations']
  • XML 解析(以 Python 为例):可以使用xml.etree.ElementTree模块来解析 XML 文件。
   import xml.etree.ElementTree as ET

   tree = ET.parse('gateway_configuration.xml')
   root = tree.getroot()
   configuration_data = []
   for config in root.findall('configuration'):
       config_dict = {}
       for child in config:
           config_dict[child.tag] = child.text
       configuration_data.append(config_dict)
动态更新配置文件
- 当采集设备发生变化时,可以通过程序来更新配置文件。例如,在 Python 中,要向 JSON 配置文件中添加一个新的配置项,可以这样做:
   new_config = {
       "key": "device3",
       "name": "Humidity Sensor",
       "type": "float",
       "server_address": "192.168.1.100",
       "firmware_version": "1.0",
       "modbus_address": ""
   }
   with open('gateway_configuration.json', 'r') as file:
       configuration_data = json.load(file)
   configuration_data['configurations'].append(new_config)
   with open('gateway_configuration.json', 'w') as file:
       json.dump(configuration_data, file, indent=4)  
  • 对于 XML 配置文件,更新操作会相对复杂一些,需要创建新的 XML 元素并插入到合适的位置。

三、使用配置管理服务(适用于大型分布式系统)

配置管理服务选型与集成
- 可以选择开源的配置管理工具,如 Apollo、Nacos 等。以 Apollo 为例,首先需要在服务器端部署 Apollo 服务,包括配置中心和管理控制台。
- 在网关项目中,集成 Apollo 客户端库。例如,在 Java 项目中,添加 Apollo 客户端的依赖,然后在配置文件(如`application.properties`)中配置 Apollo 服务器的地址和应用相关的信息。
     app.id=gateway - application
   apollo.meta=http://apollo - server - address:8080
  • 在代码中,通过 Apollo 客户端 API 来获取配置点表的信息。例如:
   import com.ctrip.framework.apollo.Config;
   import com.ctrip.framework.apollo.ConfigService;

   public class GatewayConfigurationLoader {
       public static void main(String[] args) {
           Config config = ConfigService.getAppConfig();
           String key = config.getProperty("device.key", "default_key");
           String name = config.getProperty("device.name", "default_name");
           // 其他配置项获取类似
       }
   }
动态更新与推送机制
- Apollo 配置管理服务支持配置的实时更新和推送。当在管理控制台修改配置点表后,Apollo 会自动将更新后的配置推送给所有连接的网关客户端。网关客户端可以通过实现配置更新监听器来接收并处理配置更新事件。例如,在 Java 中:
   import com.ctrip.framework.apollo.Config;
   import com.ctrip.framework.apollo.model.ConfigChange;
   import com.ctrip.framework.apollo.model.ConfigChangeEvent;
   import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
   import org.springframework.stereotype.Component;

   @Component
   public class GatewayConfigurationChangeListener {
       @ApolloConfigChangeListener
       private void onChange(ConfigChangeEvent changeEvent) {
           Config config = changeEvent.getConfig();
           for (String key : changeEvent.changedKeys()) {
               ConfigChange change = changeEvent.getChange(key);
               System.out.println("配置项 " + key + " 从 " + change.getOldValue() + " 变更为 " + change.getNewValue());
               // 根据配置项的变更进行相应的处理,如重新加载配置或更新运行时状态
           }
       }
   }  
高可用与分布式考虑
- 配置管理服务本身需要考虑高可用性和分布式部署。例如,Apollo 服务可以通过多副本部署、数据备份等方式来确保服务的可靠性。同时,网关客户端在连接配置管理服务时,也可以配置重试机制和连接池等,以应对网络故障或服务暂时不可用的情况。
  • 使用 Qt 实现网关配置点表扩展性的完整流程及代码示例。

拓展性实现二(QT)

一、使用数据库存储配置点表(以 SQLite 为例)

数据库创建与连接

在 Qt 项目中,可以使用 Qt 的 SQL 模块来连接和操作数据库。首先创建一个数据库连接:

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
    database.setDatabaseName("gateway_configuration.db");

    if (!database.open()) {
        qDebug() << "Error opening database:" << database.lastError().text();
        return -1;
    }

    // 创建表(如果表不存在)
    QSqlQuery query;
    query.exec("CREATE TABLE IF NOT EXISTS gateway_configuration ("
               "id INTEGER PRIMARY KEY AUTOINCREMENT,"
               "key TEXT,"
               "name TEXT,"
               "type TEXT,"
               "server_address TEXT,"
               "firmware_version TEXT,"
               "modbus_address TEXT"
               ")");

    // 后续操作...

    return a.exec();
}
数据访问函数

添加、查询、更新和删除数据的函数:

// 添加新的配置项
bool addConfiguration(const QString &key, const QString &name, const QString &type, const QString &serverAddress, const QString &firmwareVersion, const QString &modbusAddress) {
    QSqlQuery query;
    query.prepare("INSERT INTO gateway_configuration (key, name, type, server_address, firmware_version, modbus_address) "
                  "VALUES (:key, :name, :type, :server_address, :firmware_version, :modbus_address)");
    query.bindValue(":key", key);
    query.bindValue(":name", name);
    query.bindValue(":type", type);
    query.bindValue(":server_address", serverAddress);
    query.bindValue(":firmware_version", firmwareVersion);
    query.bindValue(":modbus_address", modbusAddress);
    return query.exec();
}

// 查询所有配置项
QList<QMap<QString, QString>> getConfigurations() {
    QList<QMap<QString, QString>> configurations;
    QSqlQuery query("SELECT * FROM gateway_configuration");
    while (query.next()) {
        QMap<QString, QString> config;
        config["id"] = query.value(0).toString();
        config["key"] = query.value(1).toString();
        config["name"] = query.value(2).toString();
        config["type"] = query.value(3).toString();
        config["server_address"] = query.value(4).toString();
        config["firmware_version"] = query.value(5).toString();
        config["modbus_address"] = query.value(6).toString();
        configurations.append(config);
    }
    return configurations;
}

// 根据 ID 查询配置项
QMap<QString, QString> getConfigurationById(int id) {
    QMap<QString, QString> config;
    QSqlQuery query(QString("SELECT * FROM gateway_configuration WHERE id = %1").arg(id));
    if (query.next()) {
        config["id"] = query.value(0).toString();
        config["key"] = query.value(1).toString();
        config["name"] = query.value(2).toString();
        config["type"] = query.value(3).toString();
        config["server_address"] = query.value(4).toString();
        config["firmware_version"] = query.value(5).toString();
        config["modbus_address"] = query.value(6).toString();
    }
    return config;
}

// 更新配置项
bool updateConfiguration(int id, const QString &key, const QString &name, const QString &type, const QString &serverAddress, const QString &firmwareVersion, const QString &modbusAddress) {
    QSqlQuery query;
    query.prepare("UPDATE gateway_configuration SET key = :key, name = :name, type = :type, server_address = :server_address, firmware_version = :firmware_version, modbus_address = :modbus_address WHERE id = :id");
    query.bindValue(":id", id);
    query.bindValue(":key", key);
    query.bindValue(":name", name);
    query.bindValue(":type", type);
    query.bindValue(":server_address", serverAddress);
    query.bindValue(":firmware_version", firmwareVersion);
    query.bindValue(":modbus_address", modbusAddress);
    return query.exec();
}

// 删除配置项
bool deleteConfiguration(int id) {
    QSqlQuery query;
    query.prepare("DELETE FROM gateway_configuration WHERE id = :id");
    query.bindValue(":id", id);
    return query.exec();
}
使用示例

在程序中使用这些函数来添加、查询、更新和删除配置项:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 添加新配置项
    addConfiguration("device1", "Temperature Sensor", "float", "192.168.1.100", "1.0", "");
    addConfiguration("device2", "Light Switch", "bool", "192.168.1.100", "1.0", "");

    // 查询所有配置项
    QList<QMap<QString, QString>> configurations = getConfigurations();
    for (const QMap<QString, QString> &config : configurations) {
        qDebug() << "Key:" << config["key"] << "Name:" << config["name"] << "Type:" << config["type"];
    }

    // 根据 ID 查询配置项
    QMap<QString, QString> configById = getConfigurationById(1);
    if (!configById.isEmpty()) {
        qDebug() << "Configuration by ID:" << configById["name"];
    }

    // 更新配置项
    updateConfiguration(1, "device1", "Updated Temperature Sensor", "float", "192.168.1.100", "1.1", "");

    // 删除配置项
    deleteConfiguration(2);

    return a.exec();
}

二、使用配置文件存储配置点表(以 JSON 格式为例)

读写 JSON 文件的函数
#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

// 读取 JSON 配置文件
QJsonDocument readJsonFile(const QString &fileName) {
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Error opening file:" << file.errorString();
        return QJsonDocument();
    }
    QString jsonData = file.readAll();
    file.close();
    return QJsonDocument::fromJson(jsonData.toUtf8());
}

// 写入 JSON 配置文件
bool writeJsonFile(const QString &fileName, const QJsonDocument &jsonDoc) {
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "Error opening file for writing:" << file.errorString();
        return false;
    }
    file.write(jsonDoc.toJson());
    file.close();
    return true;
}
操作配置数据的函数
// 添加新的配置项到 JSON 数据
void addConfigurationToJson(QJsonArray &configurations, const QString &key, const QString &name, const QString &type, const QString &serverAddress, const QString &firmwareVersion, const QString &modbusAddress) {
    QJsonObject config;
    config["key"] = key;
    config["name"] = name;
    config["type"] = type;
    config["server_address"] = serverAddress;
    config["firmware_version"] = firmwareVersion;
    config["modbus_address"] = modbusAddress;
    configurations.append(config);
}

// 根据键值查找配置项
QJsonObject findConfigurationByKey(const QJsonArray &configurations, const QString &key) {
    for (const QJsonValue &value : configurations) {
        QJsonObject config = value.toObject();
        if (config["key"].toString() == key) {
            return config;
        }
    }
    return QJsonObject();
}

// 更新配置项
bool updateConfigurationInJson(QJsonArray &configurations, const QString &key, const QString &name, const QString &type, const QString &serverAddress, const QString &firmwareVersion, const QString &modbusAddress) {
    for (QJsonValueRef value : configurations) {
        QJsonObject config = value.toObject();
        if (config["key"].toString() == key) {
            config["name"] = name;
            config["type"] = type;
            config["server_address"] = serverAddress;
            config["firmware_version"] = firmwareVersion;
            config["modbus_address"] = modbusAddress;
            return true;
        }
    }
    return false;
}

// 删除配置项
bool deleteConfigurationFromJson(QJsonArray &configurations, const QString &key) {
    QJsonArray newConfigurations;
    bool found = false;
    for (const QJsonValue &value : configurations) {
        QJsonObject config = value.toObject();
        if (config["key"].toString()!= key) {
            newConfigurations.append(config);
        } else {
            found = true;
        }
    }
    configurations = newConfigurations;
    return found;
}
使用示例
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 读取 JSON 配置文件
    QJsonDocument jsonDoc = readJsonFile("gateway_configuration.json");
    QJsonArray configurations = jsonDoc.object()["configurations"].toArray();

    // 添加新配置项
    addConfigurationToJson(configurations, "device1", "Temperature Sensor", "float", "192.168.1.100", "1.0", "");
    writeJsonFile("gateway_configuration.json", QJsonDocument(QJsonObject{{"configurations", configurations}}));

    // 查找配置项
    QJsonObject foundConfig = findConfigurationByKey(configurations, "device1");
    if (!foundConfig.isEmpty()) {
        qDebug() << "Found configuration:" << foundConfig["name"].toString();
    }

    // 更新配置项
    updateConfigurationInJson(configurations, "device1", "Updated Temperature Sensor", "float", "192.168.1.100", "1.1", "");
    writeJsonFile("gateway_configuration.json", QJsonDocument(QJsonObject{{"configurations", configurations}}));

    // 删除配置项
    bool deleted = deleteConfigurationFromJson(configurations, "device1");
    if (deleted) {
        qDebug() << "Configuration deleted successfully.";
        writeJsonFile("gateway_configuration.json", QJsonDocument(QJsonObject{{"configurations", configurations}}));
    }

    return a.exec();
}

通过以上两种方法,可以在 Qt 项目中实现网关配置点表的扩展性,根据实际需求选择合适的存储方式。如果需要更复杂的配置管理功能,可以结合 Qt 的信号与槽机制、界面设计等,构建更加完善的网关配置管理系统。

标签:点表,网关,name,type,json,key,address,query,config
From: https://blog.csdn.net/shenzhou17/article/details/143225383

相关文章

  • 统一网关Gateway
    统一网关Gateway①:为什么需要网关 ②:搭建网关服务 网关作用流程 ③:路由断言工厂 关于断言工厂为什么不是过滤器断言工厂是用来匹配请求的,比方说有很多微服务交由网关管理。每个微服务都有不同的断言工厂配置,有的微服务必须几点之前、有的微服务必须什么IP当......
  • 电瓶车检测视频分析网关AI智能分析提升电瓶车使用场景的消防安全
    随着电瓶车(电动自行车)的普及,它在城市交通中扮演着越来越重要的角色。然而,电瓶车的管理、安全监控以及维护等方面也面临着诸多挑战。人工智能(AI)技术的发展为解决这些问题提供了新的途径。电瓶车检测AI算法能够通过深度学习等技术对电瓶车及其相关行为进行智能识别和分析,为电瓶车的......
  • 烟火检测视频分析网关算法定制烟火识别技术在沿街商铺消防安全管理中的应用
    在沿街商铺的消防安全管理中,烟火检测视频分析网关算法的应用显得尤为重要。随着城市化进程的加快,沿街商铺数量激增,这些商铺在为居民生活带来便利的同时,也因店主安全意识不足、消防管理松散等问题,成为火灾隐患的高发区。因此,采用智能化的烟火识别技术,对于提升消防安全管理水平、预......
  • 海康威视AI开放平台训练数据集导入问题---解决导入自己数据集的问题(txt转json格式)
    一、问题导入首先我们先进入到开放平台中,选择物体检测最近在做一个项目,需要使用到海康威视AI开放平台来训练数据集,但是刚开始遇到了一个问题就是导入自己的数据集(txt格式转成了json格式)为啥没有用,后面查看相关文档,解决了导入自己数据集的问题,就不用在平台里标注了。二、探......
  • Golang 中使用 JSON 的一些小技巧
    临时忽略struct字段typeUserstruct{Emailstring`json:"email"`Passwordstring`json:"password"`//manymorefields…}临时忽略掉Password字段json.Marshal(struct{*UserPasswordbool`json:"password,omitempty"`}{Us......
  • 摄像机实时接入分析平台视频分析网关周界入侵智慧园区视频智能监管方案
    一、背景需求分析随着科技的不断发展,智慧园区建设已成为现代城市发展的重要方向。视频分析网关通过智能化技术提高园区的运营效率、降低成本、增强环境可持续性等具有重要作用。视频智能监管作为智慧园区安全管理体系的重要组成部分,对于提高园区的安全管理水平和保障园区的安全稳......
  • Java 解析 XML 转换为 Json
    我们使用Java开发项目时偶尔会需要使用到Xml文件的解析,一般情况下都会使用DOM4j、SAX、JDOM等方案,但这些方案比较代码编写较为繁琐。我们经常使用的Json进行数据传输或存储,如果能够将Xml快速转换为Json,将会大大减轻我们后续开发和维护的工作量。本篇博客简单介绍使用......
  • AI网关对企业的意义及如何构建 AI 网关
    随着大模型的发展,越来越多企业将生成性AI应用投入生产和业务当中,因而企业组织的系统应用也将面临前所未有的多重挑战,包括:如何遵循AI安全政策、如何理解用户行为,以及确保应用的可靠性和性能。AI网关旨在帮助企业应对AI调用的挑战及更多问题。AI网关充当组织内AI的中心访问点,通过单......
  • AI智能分析视频分析网关算法定制智能分析网关V4安全帽检测/反光衣检测/通用工服检测算
    在现代工业和社会活动中,工作场所的安全越来越受到重视。为了确保员工的安全,许多行业都制定了严格的安全规范,其中包括正确佩戴个人防护装备,如安全帽和反光衣。然而,人工监控这些规范的执行情况往往效率低下,且容易出现疏漏。随着人工智能技术的发展,AI智能分析网关应运而生,它通过先进......
  • 邮件安全网关厂商哪个好?靠谱邮件实力上榜中国网络安全行业全景册
    靠谱邮件依托在邮件云安全领域20余年的深耕,凭借丰富的邮件安全产品矩阵、持续的技术创新能力和专业的售后服务,实力上榜网络安全行业媒体FreeBuf发布的《CCSIP2023中国网络安全行业全景册》,受到行业的高度认可,成为企业认可选择的邮件网关厂商。据悉本次全景册由FreeBuf咨询顾......