通过maven导入相关依赖包
如何通过maven导入我们的包:
①、首先我们打开https://mvnrepository.com/
在搜索框中输入我们想要的依赖:
复制相关的dependency即可
把这个maven导入依赖包代码复制到pom.xml文件的下
在IDEA右边点击Maven会弹出一个框
然后刷新:
influx教程
a,下面给出一个简单的实例
insert add_test,name=YiHui,phone=110 user_id=20,email=“bangzewu@126.com”
新增一条数据,measurement为add_test, tag为name,phone, field为user_id,email
从上面的输出,简单小结一下插入的语句写法
insert + measurement + “,” + tag=value,tag=value + 空格 + field=value,field=value
tag与tag之间用逗号分隔;field与field之间用逗号分隔
tag与field之间用空格分隔
tag都是string类型,不需要引号将value包裹
field如果是string类型,需要加引号
原文链接:https://blog.youkuaiyun.com/tmlige/article/details/116204746
2023年2月7日配置wvp总结:
1.摄像头配置的时候,如果摄像头直接连接要登陆该摄像头配置网站的电脑时,要保证两者的ip不再同一个网段上,如都不能是192.168.1.xx,解决方案,把摄像头的配置网址ip改成192.168.10.xx。
2.数据库的迁移使用技巧:
(1)如果想把某台电脑上的数据库的表结构一模一样的复制到另一台电脑上,在navicat数据库管理工具上操作:
在数据库的pubic上右击,鼠标滑到转存储SQL,根据具体要求可以选择仅结构或者数据和结构。导出的sql脚本可以在另一台电脑上的navicat上的查询界面进行生成原数据库的表。
(2)如果两个数据库表结构一样,但是想导入某个表的数据,对该表点击右键,存储SQL。
3.如果想更改代码里的重复的内容,可以用替换功能。
(1)全局搜索:使用快捷键Ctrl+Shift+F打开搜索窗口,或者通过点击Edit–>Find–>Find in path打开搜索窗口.
(2)全局替换:通过快捷键Ctrl+Shift+R打开窗口,或者通过点击Edit–>Find–>Replace in path打开窗口。比搜索窗口多了填写替换内容的输入框,如下图:
4.常用docker命令:https://www.runoob.com/docker/docker-command-manual.html
docker ps :列出容器
docker exec -it 容器名(或id)bash :进入容器
docker rm -f 容器名 :删除容器
。配置文件数据库配置部分改动
2。StreamPushMapper.java等文件中列名含有大小写混合的都家了双引号。
3。postgres数据库中部分表的列属性改成了bool:
(1)将streamproxy表中的enable_remove_none_reader的数据类型从varchar(1)改成bool,(即所有bool都是由varchar(1)改过来的
user表和postgres查询语句的关键字重名了,所以需要改动一下,这里改成了users
log表的id没有设置自增功能:自行设置
<–设置序列从1开始,自增1–>
CREATE SEQUENCE user_id_seq START WITH 1
INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1;
<–设置序列–>
ALTER table log ALTER column id SET DEFAULT nextval(‘user_id_seq’);
在有的地方比如对列进行sum函数,但原来mysql用的是char类型,所以在postgres要在查询语句中加入强制类型转换::int4
influxdb 时序数据库。
获取某个容器的ip:
docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ container_name_or_id
2023.2.9
在docker上部署zlm服务器进行wvp平台的配置:
zlm的docker部署环节:
(1)在docker上安装ZLMediaKit容器:
docker run -d -p 1935:1935 -p 8080:80 -p 8554:554
-p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp
–name zlmediakit
zlmediakit/zlmediakit:master
注意:这里的端口映射尽量别改动,如果安装的时候提示端口冲突,改动映射端口后,也要在容器的配置文件
opt/media/conf/config.ini 修改对应的端口,上面代码的端口是配置文件里默认的。这里的8080可以灵活更改,是容器映射到宿主机的端口,和wvp的配置文件中media下的http-port一致。
(2)进入容器终端:docker exec -it zlmeiakit bash
注意这里要用exec命令而不是run。
(3)cd /opt/media/conf/
(4)vi config.ini
修改配置文件中的genaral的mediaserverId改成和wvp配置文件application.yaml的media下的id一致。
(5)exit
(6)docker restart 容器id(可以用docker ps 查看)
wvp配置文件的改动:
media:
id:和刚刚docker容器里的配置文件中的meidaserverid一致。
ip:写部署docker的宿主机ip
http-port:docker映射到其宿主机的端口,如这里就是8080
rtp:
enable:false
注意:这里enable一定要改成false,单端口模式,因为如果是多端口模式的话,在dokcer里并不能保证这些范围i的端口都映射出来了。
如果开启服务的时候遇到Failed to start xxx.service: Unit is masked. 可执行如下命令开启:
systemctl unmask xxx.service
systemctl start xxx.service
systemctl mask xxx.service
原文链接:https://blog.youkuaiyun.com/q2678692691/article/details/105061208
InfluxDB常用聚合函数
InfluxDB是一款由Go语言开发的以时间为主要序列的时序数据库,以下是对InfluxDB中常用的聚合和部分计算函数的简单介绍。
Count
返回一个(field)字段中的非空值的数量。
SELECT COUNT(field_name) FROM db_name;
Distinct
返回一个字段的(field)的唯一值。
SELECT DISTINCT(field_name) FROM db_name;
Mean
返回一个字段(field)中的值的算数平均值,字段类型必须是长整形或者float64。
SELECT MEAN(field) FROM db_name;
MEDIAN
从单个字段(field)中的排序值返回中间值(中位数)。字段值的类型必须是长整型或float64格式。
SELECT MEDIAN(field) FROM db_name;
SPREAD
返回字段的最小值和最大值之间的差值。数据的类型必须是长整型或float64。
SELECT SPREAD(field) FROM db_name;
SUM
返回一个字段中的所有值的和。字段的类型必须是长整型或float64。
SELECT SUM(field) from db_name;
STDDEV
返回某一字段的标准差(什么是标准差?),数据的类型必须是长整形或float64。
SELECT STDDEV(field_key) FROM db_name;
BOTTOM & TOP
返回某一字段最小、最大的几个值记录,数据的类型必须是长整形或float64。
SELECT BOTTOM/TOP(field_key,N) FROM db_name;
PS:其中N代表记录条数。
FIRST
返回某一字段时间最早的记录值,支持所有的字段类型。
SELECT FIRST(field_key) FROM db_name;
LAST
返回某一字段符合条件(where后的条件)的最新记录。
SELECT LAST(field_key) FROM db_name;
MAX & MIN
返回某一字段的最大、最小值,数据的类型必须是长整形或float64。
SELECT MAX/MIN(field_key) FROM db_name;
PERCENTILE
返回某一字段按百分比排列正序前几的记录,只支持0-100的长整形和float64类型。
SELECT PERCENTILE(field_key,N) FROM db_name;
PS:其中N代表展示正序排列第N之前的排名记录,例如N=5,则返回按百分比排列前5的记录,排列按0~100正序排列。
SAMPLE
随机返回N个某一字段的值,支持所有的数据类型。
SELECT SAMPLE(field_key,N) FROM db_name;
CUMULATIVE_SUM
计算某一字段中从符合条件的记录起,之后的每一条记录的累计和,数据的类型必须是长整形或float64。
SELECT CUMULATIVE_SUM(field_key) FROM db_name;
PS:例如某字段有三条记录[1,2,3],用以上语句查询的结果为[1,3,6]
DERIVATIVE
官方的文档中描述该函数是求该字段值的变动比率区间derivative,仔细看例子可以理解为对数据求导数。
SELECT DERIVATIVE(field_key) FROM db_name;
DIFFERENCE
求符合条件数据的差积分difference
SELECT DIFFERENCE(field_key) FROM db_name;
2.9-2.19进度总结:
一,学习如何在idea从头搭建一个springboot项目。(集成springmvc,集成Mybatis,以及mysql数据库连接)。
1。file->new->module。创建一个新的 Module,选择类型为 Spring Initializr。
2.指定 GAV 及 pom 配置信息
3.选择 Spring Boot 版本及依赖
4.集成springmvc:(spring提供的一个基于MVC设计模式的轻量级web开发框架)在POM.xml中指定springmvc依赖包:
5.集成mybatis:
6.mysql数据库连接
7.在 Springboot 的核心配置文件 application.properties 中配
置数据源。
二,学习如何在springboot上连接influx数据库。
1,首先在POM.xml文件中添加maven中依赖influxDB:
2.再在application.xml中进行添加配置信息:
spring:
influx:
url: http://localhost:8086
user: admin
password: abcd_2021
database: demo
package com.beyond.data.config;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.BatchPoints;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
@Configuration
public class InfluxDBConfig {
@Value("${spring.influx.user}")
private String userName;
@Value("${spring.influx.password}")
private String password;
@Value("${spring.influx.url}")
private String url;
//数据库
@Value("${spring.influx.database}")
private String database;
//保留策略
private String retentionPolicy;
private InfluxDB influxDB;
public InfluxDBConfig(){}
public InfluxDBConfig(String userName, String password, String url, String database) {
this.userName = userName;
this.password = password;
this.url = url;
this.database = database;
// autogen默认的数据保存策略
this.retentionPolicy = retentionPolicy == null || "".equals(retentionPolicy) ? "autogen" : retentionPolicy;
this.influxDB = influxDbBuild();
}
/**
* 设置数据保存策略 defalut 策略名 /database 数据库名/ 30d 数据保存时限30天/ 1 副本个数为1/ 结尾DEFAULT
* 表示 设为默认的策略
*/
public void createRetentionPolicy() {
String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
"defalut", database, "30d", 1);
this.query(command);
}
/**
* 连接时序数据库;获得InfluxDB
**/
private InfluxDB influxDbBuild() {
if (influxDB == null) {
influxDB = InfluxDBFactory.connect(url, userName, password);
influxDB.setDatabase(database);
}
return influxDB;
}
/**
* 插入
* @param measurement 表
* @param tags 标签
* @param fields 字段
*/
public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields) {
influxDbBuild();
Point.Builder builder = Point.measurement(measurement);
builder.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
builder.tag(tags);
builder.fields(fields);
influxDB.write(database, "", builder.build());
}
/**
* @desc 插入,带时间time
* @date 2021/3/27
*@param measurement
*@param time
*@param tags
*@param fields
* @return void
*/
public void insert(String measurement, long time, Map<String, String> tags, Map<String, Object> fields) {
influxDbBuild();
Point.Builder builder = Point.measurement(measurement);
builder.time(time, TimeUnit.MILLISECONDS);
builder.tag(tags);
builder.fields(fields);
influxDB.write(database, "", builder.build());
}
/**
* @desc influxDB开启UDP功能,默认端口:8089,默认数据库:udp,没提供代码传数据库功能接口
* @date 2021/3/13
*@param measurement
*@param time
*@param tags
*@param fields
* @return void
*/
public void insertUDP(String measurement, long time, Map<String, String> tags, Map<String, Object> fields) {
influxDbBuild();
Point.Builder builder = Point.measurement(measurement);
builder.time(time, TimeUnit.MILLISECONDS);
builder.tag(tags);
builder.fields(fields);
int udpPort = 8089;
influxDB.write(udpPort, builder.build());
}
/**
* 查询
* @param command 查询语句
* @return
*/
public QueryResult query(String command) {
influxDbBuild();
return influxDB.query(new Query(command, database));
}
/**
* @desc 查询结果处理
* @date 2021/5/12
*@param queryResult
*/
public List<Map<String, Object>> queryResultProcess(QueryResult queryResult) {
List<Map<String, Object>> mapList = new ArrayList<>();
List<QueryResult.Result> resultList = queryResult.getResults();
//把查询出的结果集转换成对应的实体对象,聚合成list
for(QueryResult.Result query : resultList){
List<QueryResult.Series> seriesList = query.getSeries();
if(seriesList != null && seriesList.size() != 0) {
for(QueryResult.Series series : seriesList){
List<String> columns = series.getColumns();
String[] keys = columns.toArray(new String[columns.size()]);
List<List<Object>> values = series.getValues();
if(values != null && values.size() != 0) {
for(List<Object> value : values){
Map<String, Object> map = new HashMap(keys.length);
for (int i = 0; i < keys.length; i++) {
map.put(keys[i], value.get(i));
}
mapList.add(map);
}
}
}
}
}
return mapList;
}
/**
* @desc InfluxDB 查询 count总条数
* @date 2021/4/8
*/
public long countResultProcess(QueryResult queryResult) {
long count = 0;
List<Map<String, Object>> list = queryResultProcess(queryResult);
if(list != null && list.size() != 0) {
Map<String, Object> map = list.get(0);
double num = (Double)map.get("count");
count = new Double(num).longValue();
}
return count;
}
/**
* 查询
* @param dbName 创建数据库
* @return
*/
public void createDB(String dbName) {
influxDbBuild();
influxDB.createDatabase(dbName);
}
/**
* 批量写入测点
*
* @param batchPoints
*/
public void batchInsert(BatchPoints batchPoints) {
influxDbBuild();
influxDB.write(batchPoints);
}
/**
* 批量写入数据
*
* @param database
* 数据库
* @param retentionPolicy
* 保存策略
* @param consistency
* 一致性
* @param records
* 要保存的数据(调用BatchPoints.lineProtocol()可得到一条record)
*/
public void batchInsert(final String database, final String retentionPolicy,
final InfluxDB.ConsistencyLevel consistency, final List<String> records) {
influxDbBuild();
influxDB.write(database, retentionPolicy, consistency, records);
}
/**
* @desc 批量写入数据
* @date 2021/3/19
*@param consistency
*@param records
*/
public void batchInsert(final InfluxDB.ConsistencyLevel consistency, final List<String> records) {
influxDbBuild();
influxDB.write(database, "", consistency, records);
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getRetentionPolicy() {
return retentionPolicy;
}
public void setRetentionPolicy(String retentionPolicy) {
this.retentionPolicy = retentionPolicy;
}
public InfluxDB getInfluxDB() {
return influxDB;
}
public void setInfluxDB(InfluxDB influxDB) {
this.influxDB = influxDB;
}
}
三,利用连接好的influx数据库进行接口编写(写了前六个)
详细见代码。
springboot连接influx数据库的查询结果格式:
三、MQTT重要概念
3.1 MQTT Client
publisher 和 subscriber 都属于 MQTT Client,之所以有发布者和订阅者这个概念,其实是一种相对的概念,就是指当前客户端是在发布消息还是在接收消息,发布和订阅的功能也可以由同一个 MQTT Client 实现。
MQTT 客户端是运行 MQTT 库并通过网络连接到 MQTT 代理的任何设备(从微控制器到成熟的服务器)。例如,MQTT 客户端可以是一个非常小的、资源受限的设备,它通过无线网络进行连接并具有一个最低限度的库。基本上,任何使用 TCP/IP 协议使用 MQTT 设备的都可以称之为 MQTT Client。MQTT 协议的客户端实现非常简单直接,易于实施是 MQTT 非常适合小型设备的原因之一。MQTT 客户端库可用于多种编程语言。例如,Android、Arduino、C、C++、C#、Go、iOS、Java、JavaScript 和 .NET。
3.2 MQTT Broker
与 MQTT Client 对应的就是 MQTT Broker,Broker 是任何发布/订阅协议的核心,根据实现的不同,代理可以处理多达数百万连接的 MQTT Client。
Broker 负责接收所有消息,过滤消息,确定是哪个Client 订阅了每条消息,并将消息发送给对应的 Client,Broker 还负责保存会话数据,这些数据包括订阅的和错过的消息。Broker 还负责客户端的身份验证和授权。
3.3 MQTT Connection
MQTT 协议基于 TCP/IP。客户端和代理都需要有一个 TCP/IP 协议支持。
MQTT 连接始终位于一个客户端和代理之间。客户端从不直接相互连接。要发起连接,客户端向代理发送 CONNECT 消息。代理使用 CONNACK 消息和状态代码进行响应。建立连接后,代理将保持打开状态,直到客户端发送断开连接命令或连接中断。
3.4 MQTT主要参数
ClientId:ClientId 的长度可以是 1-23 个字符,在一个服务器上 ClientId 不能重复。如果超过 23 个字符,则服务器返回 CONNACK 消息中的返回码为 Identifier Rejected。在 MQTT 3.1.1 中,如果您不需要代理持有状态,您可以发送一个空的 ClientId。空的 ClientId 导致连接没有任何状态。在这种情况下,clean session 标志必须设置为 true,否则代理将拒绝连接。
Clean Session:Clean Session 标志告诉代理客户端是否要建立持久会话。在持久会话 (CleanSession = false) 中,代理存储客户端的所有订阅以及以服务质量(QoS)级别 1 或 2 订阅的客户端的所有丢失消息。 如果会话不是持久的 (CleanSession = true ),代理不为客户端存储任何内容,并清除任何先前持久会话中的所有信息。
Username/Password:MQTT 可以发送用户名和密码进行客户端认证和授权。但是,如果此信息未加密或散列,则密码将以纯文本形式发送。我们强烈建议将用户名和密码与安全传输一起使用。像 HiveMQ 这样的代理可以使用 SSL 证书对客户端进行身份验证,因此不需要用户名和密码。
Will Message:LastWillxxx 表示的是遗愿,client 在连接 broker 的时候将会设立一个遗愿,这个遗愿会保存在 broker 中,当 client 因为非正常原因断开与 broker 的连接时,broker 会将遗愿发送给订阅了这个 topic(订阅遗愿的 topic)的 client。
KeepAlive:keepAlive 是 client 在连接建立时与 broker 通信的时间间隔,通常以秒为单位。这个时间指的是 client 与 broker 在不发送消息下所能承受的最大时长。
QOS:此数字表示消息的服务质量 (QoS)。有三个级别:0、1 和 2。服务级别决定了消息到达预期接收者(客户端或代理)的保证类型。
Payload:这个是每条消息的实际内容。MQTT 是数据无关性的。可以发送任何文本、图像、加密数据以及二进制数据。
timeout:MQTT会尝试接收数据,直到timeout时间到后才会退出。
原文链接:https://blog.youkuaiyun.com/weixin_45629315/article/details/122679643