视频信息如何作为物联网管理的一部分,一直是我们公司比较关注的一项内容,哪些内容应该被纳入物联网管理范畴?通过这篇文章,我们一起来探讨一下。

准备工作

  • 视频直播设备,比如:IPC 网络摄像机,或者可以模拟推流的ffmpeg,IPC 拍摄视频,自定义码流(比如500kbit/s),自定义分辨率(1080P),标准协议(RTMP);
  • Wi-Fi 或 有线网络是比较容易的选择,有4G当然更加灵活,这个根据具体需求来确定选择哪类传输方式;
  • 流媒体服务器,比如:YiMEDIA,可以实现流媒体服务支持,推流/拉流,状态查询;
  • 物联网插件,具备从流媒体服务器获取IPC信息,流信息,并且与物联网服务器交互,比如:YiCONNECT;

过程剖析

IPC 端

  • 首先,必须是 IPC,这样才能通过网络推流;
  • 其次,具备 RTMP 推流协议,如果只是支持 RTSP,需要一个转换器把 RTSP流 转换成 RTMP流 推送出去;
  • 再次,编码类型H264,分辨率看摄像头,一般都可以1080P,码流至少要达到 500kbps 以上,否则不一定能推流成功,且视频不清晰;
  • 再一次,如果需要音频上传,需要用 aac 编码;
  • 最后,成功推流。如果不行,建议咨询 IPC 厂家。

YiMEDIA 端

流媒体服务器,这里以我司 YiMEDIA 为基础,简单介绍一些。

  • 流媒体服务器开启 RTMP 通道,一般是 TCP 1935 端口号;
  • 开启推流验证,如果验证不通过,就断开推流客户端的连接,可以用随机数的方式,YiMEDIA 才有回调应用服务器确认连接安全性;
  • 推流/拉流 URL 建议采用: rtmp://[IPADDRESS]/[IPC]/[auth_key],或 rtmp://[IPADDRESS]/[IPC]/[MAIN/SUB]?key=[auth_key] ;
  • YiMEDIA 开启 NVR/DVR 功能,记录所有的视频信息;

YiCONNECT 端

为了将视频流数据状态和信息发送到 YiCONNECT,需要开发一个插件,获取 流信息 后,以 Thingsboard 能接收的方式发送。

  • 编写 Thingsboard gateway 应用程序,以便支持 视频流 信息的转发和解析;
开启 rest.json 服务
编写 YiMEDIA 丢过来的回调请求回应信息
  • 解析 [IPC] 和 [auth_key] 字段,并验证 auth_key 是否满足要求;
  • YiCONNECT 端新建 Gateway 网关设备,保持验证码一致;

结果预览

YiMEDIA 状态查看

  • 客户端状态
    clients.png
  • 流状态
    streams.png

YiCONNECT

  • 设备列表表
    devices.png
  • 视频流列表
    videos.png

图像预览

可以通过 VLC 播放器播放:

    1. rtmp 流: rtmp://ipaddress/ON400H16DM0FZ20210308002/high,基本处于实时播放,1-3秒
    2. flv 格式: http://ipaddress/ON400H16DM0FZ20210308002/high.flv,准实时播放,3-5秒
    3. m3u8 格式:http://ipaddress/ON400H16DM0FZ20210308002/high.m3u8,延时比较大,几秒到几十秒
    • 4G 摄像头抓图
      4g.png
    • 半夜红外线开启抓图
      midnight.jpg

    方案详解

    YiCAMERA-solution.png

    此次移植工作以中国移动 ML302 模组为基础,亿琪软件 YiDTU 设备为原型,开发基于 Modbus Master 应用;
    传统模式下,DTU 都是以透传为主要工作,所有的业务需求都是从服务器端发出,而 YiDTU 是作为边缘计算的角色,在工业现场就已经把数据处理做完;

    yigate-yidtu.png

    准备工作

    硬件设备

    • YiDTU 设备一台
      亿琪软件 YiDTU 设备内置 UART 转 RS485 模块,对外连接 RS485 双线设备,如:YiSensor 模拟量采集模块;对于开发而言,那就是主要针对 UART 串口操作;
    • Micro USB 线一根
      用于操作 YiDTU 设备:AT 串口操作,烧录操作;
    • RS485 设备若干
      可用 USB 转 RS485 转换器代替(需配合 modbus slave 软件使用);有支持 Modbus Slave 设备最好;准备了两个:模拟量 4-20mA 和 开关量各一个;
    • 9~30V 直流电源一个
      支持最大 2A 电流的直流电源一个,用于给 YiDTU 设备供电;
    • 将以上硬件设备连接好

    软件 SDK

    • 从中国移动物联网公司获取 ML302 相关 SDK,;
    • 确保 SDK 编译正常;
    • 烧录基本应用成功;

    移植过程

    Modbus Master 库

    • https://github.com/jiekechoo/ModBus-Master.git 获取源代码,使用 STM32 环境编译成功,确保你的环境没问题;
    • 将 Modbus_Master 目录移植到 ML302 工程中 src/demo/modbus 下,根据需求删除不必要的组件功能;
    • ML302 环境下编译通过,确保没有错误出现;
    • Modbus 枚举值要重新定义
    typedef enum
    {
      // Modbus function codes for bit access
      ku8MBReadCoils = 0x01,          ///< Modbus function 0x01 Read Coils
      ku8MBReadDiscreteInputs = 0x02, ///< Modbus function 0x02 Read Discrete Inputs
      ku8MBWriteSingleCoil = 0x05,    ///< Modbus function 0x05 Write Single Coil
      ku8MBWriteMultipleCoils = 0x0F, ///< Modbus function 0x0F Write Multiple Coils
    
      // Modbus function codes for 16 bit access
      ku8MBReadHoldingRegisters = 0x03,      ///< Modbus function 0x03 Read Holding Registers
      ku8MBReadInputRegisters = 0x04,        ///< Modbus function 0x04 Read Input Registers
      ku8MBWriteSingleRegister = 0x06,       ///< Modbus function 0x06 Write Single Register
      ku8MBWriteMultipleRegisters = 0x10,    ///< Modbus function 0x10 Write Multiple Registers
      ku8MBMaskWriteRegister = 0x16,         ///< Modbus function 0x16 Mask Write Register
      ku8MBReadWriteMultipleRegisters = 0x17 ///< Modbus function 0x17 Read Write Multiple Registers
    } modbusFunc;

    串口接收支持

    • 串口接收任务中,将收到的内容复制到全局变量中,目的是把 Modbus Slave 回复的内容获取到,交给 Modbus 组件使用;
    extern uint8_t u8ModbusADU[1024];
    extern uint8_t u8ModbusADUSize;
    
    // 接收处理函数中
    {
                u8ModbusADUSize = uart_buf_len;
                memcpy(u8ModbusADU, uart_buf, u8ModbusADUSize);
    }
    • 接收完成后,创建一个 信号量,通知 Modbus 组件来处理;
    {
                    uart_buf_len = 0;
                    recv_count = 0;
                    osSignalSet(OC_Main_TaskHandle, 0x0004);
    }

    Modbus 组件

    • 将 Modbus 组件中接收处理替换成信号量等待,超时重置接收缓冲区;
      // 串口收到数据信号量,2000ms 超时
      osEvent osevent = osSignalWait(0x0004, ku16MBResponseTimeout);
      if (osevent.status == osEventTimeout)
      {
        u8MBStatus = ku8MBResponseTimedOut;
        memset(u8ModbusADU, 0, sizeof(u8ModbusADU));
        u8ModbusADUSize = 0;
      }
    • Modbus 发送函数重写
    uint8_t Modbus_Master_Write(uint8_t *buf, uint8_t length)
    {
      //  if(HAL_UART_Transmit(&huart2 ,(uint8_t *)buf,length,0xff))
      if (cm_uart_send_no_cache(OPENCPU_MAIN_URAT, (uint8_t *)buf, length, 0xff) == 0)
      {
        return HAL_ERROR;
      }
      else
      {
        return HAL_OK;
      }
    }
    • 如果有 CS 控制口 IO,需要自定义相关函数
    #if 0
      // transmit request RS485接口是需要每次发送前改变接口的模式
      
      if (_preTransmission)
      {
        _preTransmission();
      }
    #endif
    
      //串口发送数据
      Modbus_Master_Write(u8ModbusADU, u8ModbusADUSize);
      u8ModbusADUSize = 0;
    
    #if 0
    // transmit request RS485接口是需要每次发送后改变接口的模式
          if (_postTransmission)
      {
        _postTransmission();
      }
    #endif

    移植过程比较简单,细节需要一定的嵌入式和 C 语言基础。

    效果展示

    在 YiDTU 业务逻辑中增加相应的功能模块,把数据传输到云平台,这样,就可以及时获取现场的模拟量数据。
    PSX_20210119_151717.jpg

    前期,发表过多个系列文章关于如何无缝扩展 ThingsBoard 功能,其实在实施过程中,还是遇到很多问题,需要提前注意!

    独立于 ThingsBoard 外的功能模块注意要点

    • 功能模块需要能够独立运行,不管是服务也好,controller 也罢,都要能够正常运行,就类似单元测试跑通,才可以融入到 ThingsBoard 中;
    • 数据表要独立成 sql 文件,便于移植到 ThingsBoard 库中,最好不要跟原有数据表有关联或冲突,尤其不能冲突;

      • 调用系统库表,新建的 Entity 要注意 column 名字于原有一样,使用 @Column(name = "foo_bar"),否则 Bean 建立失败;
      • 如果 Entity 有嵌套调用 POJO,需要将 Entity 设置成 @Proxy(lazy = false),关闭懒加载,否则无法查询数据;
    • 打包功能模块,需要将 Spring Boot 项目 target 中的 .original 文件安装到本地 maven 库,或者修改 pom.xml 文件来改变 maven 打包规则;
    • 功能模块中的附件,图片,pdf 模板,直接在功能模块 jar 包中,不需要单独导入 ThingsBoard 中;
    • Controller 要单独命名,不能与 ThingsBoard 冲突,API 路径可以复用原有路径,比如:原有是 /api/report/foo,可以增加新的 /api/report/bar;
    • Domain/POJO/Repository等,要独立命名,因为我们以 maven jar 包方式融入 ThingsBoard,都交给 spring 来管理,所以命名要独立;

    众所周知,Kubernetes(k8s)太火了,太牛了,咱们把部署在 ThingsBoard 上更是理所当然。一句话总结:步骤很简单,过程很艰辛!

    准备 Docker 和 Kubernetes 环境

    安装 Docker Desktop CE 版本

    • 笔者使用的老版本 MacBook Pro 13,下载安装 Docker Desktop CE 版本,这个比较简单,官方下载,安装即可完成,启动。
      docker.png
    • 启用 Docker Desktop 中 Kubernetes
      kubernetes-in-docker.png

    哇塞,是不是太简单了?当然不会那么容易搞定,你会一直出现 “Starting” 的状态,别傻等,要去 Google 一下。关键字:如何成功启动 Docker 自带的 Kubernetes? 总之,你一定要找到办法解决你的 Kubernetes 成功启动。

    安装 Kubenetes 本地版本

    • 安装 Kubernetes,就是简单,本地安装搞定
    # brew install kubernetes-cli
    
    # kubectl version --client
    Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-12T01:09:16Z", GoVersion:"go1.15.4", Compiler:"gc", Platform:"darwin/amd64"}
    • 为了让 Docker Desktop 启动 k8s,需下载相关的 docker images,需要通过一个脚本 docker-images-k8s.sh,然后运行,从 aliyun 下载 docker image 比较快。
    #!/bin/bash
    
    set -e
    KUBE_VERSION=v1.19.3
    KUBE_PAUSE_VERSION=3.2
    ETCD_VERSION=3.4.13-0
    COREDNS_VERSION=1.7.0
    GCR_URL=k8s.gcr.io
    ALIYUN_URL=registry.cn-hangzhou.aliyuncs.com/google_containers
    
    # get images
    images=(kube-proxy:${KUBE_VERSION}
        kube-scheduler:${KUBE_VERSION}
        kube-controller-manager:${KUBE_VERSION}
        kube-apiserver:${KUBE_VERSION}
        pause:${KUBE_PAUSE_VERSION}
        etcd:${ETCD_VERSION}
        coredns:${COREDNS_VERSION})
    
    for imageName in ${images[@]} ; do
        docker pull $ALIYUN_URL/$imageName
        docker tag $ALIYUN_URL/$imageName $GCR_URL/$imageName
        docker rmi $ALIYUN_URL/$imageName
    done
    
    # show images
    docker images
    
    • 为了查看 k8s 运行状态,web 管理工具 kubernetes dashboard 自然少不了,新建 docker-images-dashboard.sh,运行
    #!/bin/bash
    
    set -e
    KUBE_DASHBOARD_VERSION=v2.0.3
    METRICS_SCRAPER=v1.0.4
    KUBENETESUI_URL=kubernetesui
    ALIYUN_KUBENETESUI_URL=registry.cn-hangzhou.aliyuncs.com/kubernetes_ns
    
    # get images (ui)
    imagesui=(dashboard:${KUBE_DASHBOARD_VERSION}
        metrics-scraper:${METRICS_SCRAPER})
    
    for imageName in ${imagesui[@]} ; do
        docker pull $ALIYUN_KUBENETESUI_URL/$imageName
        docker tag $ALIYUN_KUBENETESUI_URL/$imageName $KUBENETESUI_URL/$imageName
        docker rmi $ALIYUN_KUBENETESUI_URL/$imageName
    done
    
    # show images
    docker images
    
    • 再去看 Docker Desktop 中已经启动 k8s了,耐心一点,这个时间比较长,验证一下,发现 Server Version 出现了证明服务器安装成功,且客户端可以连接上
    # kubectl version
    Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-12T01:09:16Z", GoVersion:"go1.15.4", Compiler:"gc", Platform:"darwin/amd64"}
    Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
    # kubectl apply -f k8s-dashboard.yaml
    
    namespace/kubernetes-dashboard created
    serviceaccount/kubernetes-dashboard created
    service/kubernetes-dashboard created
    secret/kubernetes-dashboard-certs created
    secret/kubernetes-dashboard-csrf created
    secret/kubernetes-dashboard-key-holder created
    configmap/kubernetes-dashboard-settings created
    role.rbac.authorization.k8s.io/kubernetes-dashboard created
    clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
    rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
    clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
    deployment.apps/kubernetes-dashboard created
    service/dashboard-metrics-scraper created
    deployment.apps/dashboard-metrics-scraper created
    
    # kubectl proxy                    
    Starting to serve on 127.0.0.1:8001
    • 启动成功后,打开浏览器,就可以登陆 Dashboard
      要么证书登陆,要么 token 登陆,先执行:
    TOKEN=$(kubectl -n kube-system describe secret default| awk '$1=="token:"{print $2}')
    kubectl config set-credentials docker-desktop --token="${TOKEN}"
    echo $TOKEN

    显示的内容就是 token

    1. 证书登陆时,选择 ~/.kube/config
    2. token 登陆就是上面那串
      k8s-dashbaord.png

    登陆成功后
    k8s-dashbaord-home.png

    安装 ThingsBoard 到 k8s

    安装 ThingsBoard

    根据官方文档,照着执行就好:https://github.com/thingsboard/thingsboard/tree/master/k8s

    • 保证网络畅通,因为需要从 docker hub 下载 images,建议用国内的镜像地址
    • 过程比较麻烦,不好监控,只能不停的刷 docker images 命令查看是不是把镜像拉下来了
    REPOSITORY                            TAG                                              IMAGE ID            CREATED             SIZE
    zookeeper                             3.5                                              ce6733a90146        3 days ago          245MB
    postgres                              12                                               386fd8c60839        3 days ago          314MB
    k8s.gcr.io/ingress-nginx/controller   <none>                                           81d7cdfa4169        9 days ago          280MB
    jettech/kube-webhook-certgen          v1.5.0                                           344297e197b6        3 weeks ago         44.7MB
    docker/desktop-kubernetes             kubernetes-v1.19.3-cni-v0.8.5-critools-v1.17.0   7f85afe431d8        5 weeks ago         285MB
    k8s.gcr.io/kube-proxy                 v1.19.3                                          cdef7632a242        5 weeks ago         118MB
    k8s.gcr.io/kube-apiserver             v1.19.3                                          a301be0cd44b        5 weeks ago         119MB
    k8s.gcr.io/kube-scheduler             v1.19.3                                          aaefbfa906bd        5 weeks ago         45.7MB
    k8s.gcr.io/kube-controller-manager    v1.19.3                                          9b60aca1d818        5 weeks ago         111MB
    thingsboard/tb-coap-transport         latest                                           5635dd5c4fe6        2 months ago        865MB
    thingsboard/tb-http-transport         latest                                           7f60b6a3bd83        2 months ago        864MB
    thingsboard/tb-mqtt-transport         latest                                           8dfe9a5bc20d        2 months ago        864MB
    thingsboard/tb-node                   latest                                           a66803235c46        2 months ago        1.09GB
    thingsboard/tb-web-ui                 latest                                           e215f4aa841a        2 months ago        426MB
    thingsboard/tb-js-executor            latest                                           7c4fdfa00e27        2 months ago        494MB
    k8s.gcr.io/etcd                       3.4.13-0                                         0369cf4303ff        2 months ago        253MB
    kubernetesui/dashboard                v2.0.3                                           503bc4b7440b        5 months ago        225MB
    k8s.gcr.io/coredns                    1.7.0                                            bfe3a36ebd25        5 months ago        45.2MB
    redis                                 4.0                                              191c4017dcdd        7 months ago        89.3MB
    kubernetesui/metrics-scraper          v1.0.4                                           86262685d9ab        8 months ago        36.9MB
    docker/desktop-storage-provisioner    v1.1                                             e704287ce753        8 months ago        41.8MB
    docker/desktop-vpnkit-controller      v1.0                                             79da37e5a3aa        8 months ago        36.6MB
    k8s.gcr.io/pause                      3.2                                              80d28bedfe5d        9 months ago        683kB
    wurstmeister/kafka                    2.12-2.2.1                                       86a9c7e5fd97        11 months ago       422MB
    • 过了很长一段时间,有可能几个小时后,你查看 docker ps
    CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS               NAMES
    a9d8b9a28efc        e704287ce753                    "/storage-provisione…"   6 minutes ago       Up 6 minutes                            k8s_storage-provisioner_storage-provisioner_kube-system_50005a87-62d2-45a0-a39e-c34af43d24c9_3
    83e1a62bb612        aaefbfa906bd                    "kube-scheduler --au…"   6 minutes ago       Up 6 minutes                            k8s_kube-scheduler_kube-scheduler-docker-desktop_kube-system_ee4c94eb845abf1878fb3c4c489b1365_7
    b4e4d52ae0bc        thingsboard/tb-node             "start-tb-node.sh"       7 hours ago         Up 7 hours                              k8s_server_tb-node-5b47bb8bd6-x8g8b_thingsboard_532519fd-7441-4a10-a0b3-3458bb9784a3_5
    462b9a657c4f        thingsboard/tb-node             "start-tb-node.sh"       7 hours ago         Up 7 hours                              k8s_server_tb-node-5b47bb8bd6-vqrvb_thingsboard_3f25d857-1624-4d27-90a5-2c54c35747ee_5
    4f3a74233acd        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-vvb9v_thingsboard_46063547-8f06-4e81-85b4-00cb4b2a5f42_7
    211329243cdd        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-l5gmw_thingsboard_29f294c1-5fd0-44a5-98a0-3880b6fe7126_7
    3a6f946e86be        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-h8zqk_thingsboard_82bc9e2b-5db7-409a-9be5-4e7c21f481b8_6
    28085da4bbae        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-ftwf8_thingsboard_0c3f60a2-fd08-4951-9d98-80d08bfa439c_6
    ed33cf23175c        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-h2vkl_thingsboard_990be16d-12d8-4f7d-8ce4-1ef4a83ac31b_7
    6b7fc0bd2fbb        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-pwc4z_thingsboard_28c0106c-9587-466f-90b3-b3af6eaed7ea_7
    520ed4711677        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-gvx2g_thingsboard_afeb8b5c-ab53-48ba-927f-2d20b5fc6c3b_6
    5baeda96c4a3        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-2z89t_thingsboard_d7ec851c-8648-465a-a855-0a23575e3c3b_6
    81f692bc2768        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-7rl82_thingsboard_08864e79-2af0-42b5-b592-4c1a2db1d5cd_6
    cb8bf860467a        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-ljwz8_thingsboard_92de7aab-fca3-4e0c-ac3e-02213603d359_7
    917ba1ee6732        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-c27qd_thingsboard_0c79ed1e-1d65-4d46-a7b1-08de77402549_6
    0ada7d6b48b9        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-k4ncf_thingsboard_cdd283fc-d0a2-45b6-b533-00dd4d38e782_7
    ffc91b31b24c        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-5p9tg_thingsboard_87e80c57-0f84-43eb-bf24-13cc309e4cec_7
    13b6d7dfb387        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-zvgrp_thingsboard_1fad5bb8-5793-48e7-8dcc-7cbaf0475192_6
    0f63ffec3cbb        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-fvvrx_thingsboard_88c65221-c5d3-419d-a155-21cfee3b7157_7
    29c432f70609        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-zvd2t_thingsboard_e0315452-8b8f-4c0a-9488-d56e296ec962_7
    58a2f29e2f6a        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-gpndh_thingsboard_99c29bd4-cb0f-4fb8-8061-ebdda21359de_7
    637a32ae8d4d        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-r2r5b_thingsboard_6ba2cc34-d6bb-4c14-96c8-0c11e20fd051_7
    0d49592908fd        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-j756s_thingsboard_0be1997a-4d1b-4d01-a3ab-55d6e468f39d_7
    5e342a30e5c6        thingsboard/tb-js-executor      "start-js-executor.sh"   7 hours ago         Up 7 hours                              k8s_server_tb-js-executor-56bbb8f446-9mmf2_thingsboard_97fc3fa7-ad20-4ffc-a34a-cda7aba93305_7
    044277041f7a        thingsboard/tb-mqtt-transport   "start-tb-mqtt-trans…"   7 hours ago         Up 7 hours                              k8s_server_tb-mqtt-transport-fb5f5d5cd-xkwcn_thingsboard_d91bc9c9-de41-4866-8fe1-03831af3a58c_3
    e7b427121ff2        thingsboard/tb-http-transport   "start-tb-http-trans…"   7 hours ago         Up 7 hours                              k8s_server_tb-http-transport-64f6f66bc7-zzvqb_thingsboard_520ed11c-239e-4083-919b-fec38277f233_3
    a2a4da430f0d        thingsboard/tb-http-transport   "start-tb-http-trans…"   7 hours ago         Up 7 hours                              k8s_server_tb-http-transport-64f6f66bc7-ztmng_thingsboard_0e628481-0398-4ddd-ad97-31c5987796f9_3
    2749cf276c80        wurstmeister/kafka              "start-kafka.sh"         7 hours ago         Up 7 hours                              k8s_server_tb-kafka-78957b6557-fc8js_thingsboard_2a3d3e60-0b40-45ba-91da-70f29f270a04_5
    f296ce350482        thingsboard/tb-mqtt-transport   "start-tb-mqtt-trans…"   7 hours ago         Up 7 hours                              k8s_server_tb-mqtt-transport-fb5f5d5cd-bs4tw_thingsboard_ef25b3b1-658e-4e4c-bd1c-a0ca2ab20ce4_3
    d7ebb30d2fc7        postgres                        "docker-entrypoint.s…"   7 hours ago         Up 7 hours                              k8s_postgres_postgres-5cf775766f-clf89_thingsboard_599ecf9f-068c-416e-ab73-95760f1099db_1
    2ad0a6662ca9        thingsboard/tb-coap-transport   "start-tb-coap-trans…"   7 hours ago         Up 7 hours                              k8s_server_tb-coap-transport-59cc8bd7bc-82zfk_thingsboard_73404a55-e170-4441-b733-5417db6461ad_1
    33c4da97f3d7        thingsboard/tb-coap-transport   "start-tb-coap-trans…"   7 hours ago         Up 7 hours                              k8s_server_tb-coap-transport-59cc8bd7bc-g8jdw_thingsboard_a48518d7-c929-4a1f-bcc8-c16fdf903fbf_1
    3f8d5b8e9d9f        thingsboard/tb-web-ui           "start-web-ui.sh"        7 hours ago         Up 7 hours                              k8s_server_tb-web-ui-5958f67cc-lg974_thingsboard_5de819ae-f832-4ab6-bdce-0f29daf037ff_1
    beb462957a30        redis                           "docker-entrypoint.s…"   7 hours ago         Up 7 hours                              k8s_server_tb-redis-7fb674db9-pzndj_thingsboard_6ff6ba21-933d-4366-89eb-3d815f5282c9_1
    e24d2ea2e00a        thingsboard/tb-web-ui           "start-web-ui.sh"        7 hours ago         Up 7 hours                              k8s_server_tb-web-ui-5958f67cc-4k4cj_thingsboard_6f3795e9-ded9-46b8-8067-b4afd63f2571_1
    c2161ce93009        zookeeper                       "/docker-entrypoint.…"   7 hours ago         Up 7 hours                              k8s_server_zookeeper-547c6ffb99-bq42m_thingsboard_11a1e06d-bbf1-4b55-bab5-7d4e4b876f20_1
    4e02d9bde8ab        79da37e5a3aa                    "/kube-vpnkit-forwar…"   7 hours ago         Up 7 hours                              k8s_vpnkit-controller_vpnkit-controller_kube-system_6fa3177c-f779-414d-8acb-1342dd87849b_1
    30f7af7ffa00        kubernetesui/dashboard          "/dashboard --insecu…"   7 hours ago         Up 7 hours                              k8s_kubernetes-dashboard_kubernetes-dashboard-5dbf55bd9d-bcc2v_kubernetes-dashboard_1e414605-d8c1-4918-8e9b-18bc2c01efe6_1
    517bc1b7ac3e        81d7cdfa4169                    "/usr/bin/dumb-init …"   7 hours ago         Up 7 hours                              k8s_controller_ingress-nginx-controller-c4f944d4d-wcqxv_ingress-nginx_329aa6a7-2ee5-4747-b77d-82182d9a872f_1
    d674f87354ca        86262685d9ab                    "/metrics-sidecar"       7 hours ago         Up 7 hours                              k8s_dashboard-metrics-scraper_dashboard-metrics-scraper-7b59f7d4df-5dkwl_kubernetes-dashboard_3235eff1-3822-4138-8d0e-d45de95d3cbf_1
    faf05611eaa3        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-gvx2g_thingsboard_afeb8b5c-ab53-48ba-927f-2d20b5fc6c3b_1
    1a1956a65635        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-coap-transport-59cc8bd7bc-82zfk_thingsboard_73404a55-e170-4441-b733-5417db6461ad_1
    d5a382ca986e        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-pwc4z_thingsboard_28c0106c-9587-466f-90b3-b3af6eaed7ea_1
    c80049396050        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-kafka-78957b6557-fc8js_thingsboard_2a3d3e60-0b40-45ba-91da-70f29f270a04_1
    7b192ede32e5        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-coap-transport-59cc8bd7bc-g8jdw_thingsboard_a48518d7-c929-4a1f-bcc8-c16fdf903fbf_1
    c33e9576e5a9        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-http-transport-64f6f66bc7-zzvqb_thingsboard_520ed11c-239e-4083-919b-fec38277f233_1
    6e90c5e851b7        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-h2vkl_thingsboard_990be16d-12d8-4f7d-8ce4-1ef4a83ac31b_1
    e74011796607        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-ftwf8_thingsboard_0c3f60a2-fd08-4951-9d98-80d08bfa439c_1
    8e7b08eaf0e4        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-7rl82_thingsboard_08864e79-2af0-42b5-b592-4c1a2db1d5cd_1
    fd3c552a04ee        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-vvb9v_thingsboard_46063547-8f06-4e81-85b4-00cb4b2a5f42_1
    d3dc754a1f71        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-l5gmw_thingsboard_29f294c1-5fd0-44a5-98a0-3880b6fe7126_1
    372fd6514108        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-gpndh_thingsboard_99c29bd4-cb0f-4fb8-8061-ebdda21359de_1
    caf096a5bf42        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-node-5b47bb8bd6-x8g8b_thingsboard_532519fd-7441-4a10-a0b3-3458bb9784a3_1
    a80bbd2267ec        bfe3a36ebd25                    "/coredns -conf /etc…"   7 hours ago         Up 7 hours                              k8s_coredns_coredns-f9fd979d6-ff45j_kube-system_df1c5b8b-26f5-48cc-a853-c050090e69ef_1
    1f1b01587d81        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-redis-7fb674db9-pzndj_thingsboard_6ff6ba21-933d-4366-89eb-3d815f5282c9_1
    992b5afa6aa1        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-web-ui-5958f67cc-lg974_thingsboard_5de819ae-f832-4ab6-bdce-0f29daf037ff_1
    271ad2fced2b        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-fvvrx_thingsboard_88c65221-c5d3-419d-a155-21cfee3b7157_1
    344ddec06f1e        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-h8zqk_thingsboard_82bc9e2b-5db7-409a-9be5-4e7c21f481b8_1
    6ad3af03d452        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_vpnkit-controller_kube-system_6fa3177c-f779-414d-8acb-1342dd87849b_1
    413d3e3fef5f        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-http-transport-64f6f66bc7-ztmng_thingsboard_0e628481-0398-4ddd-ad97-31c5987796f9_1
    b42279032251        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-zvd2t_thingsboard_e0315452-8b8f-4c0a-9488-d56e296ec962_1
    472cd017176e        bfe3a36ebd25                    "/coredns -conf /etc…"   7 hours ago         Up 7 hours                              k8s_coredns_coredns-f9fd979d6-k54r2_kube-system_9355c0e5-b8fc-4c3c-9644-89749adeee97_1
    3e0fe843bcbe        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_postgres-5cf775766f-clf89_thingsboard_599ecf9f-068c-416e-ab73-95760f1099db_1
    e199dac37dec        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-mqtt-transport-fb5f5d5cd-xkwcn_thingsboard_d91bc9c9-de41-4866-8fe1-03831af3a58c_1
    e72505d9d064        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-ljwz8_thingsboard_92de7aab-fca3-4e0c-ac3e-02213603d359_1
    43362e2031d8        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-2z89t_thingsboard_d7ec851c-8648-465a-a855-0a23575e3c3b_1
    9c876bbc23be        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-c27qd_thingsboard_0c79ed1e-1d65-4d46-a7b1-08de77402549_1
    11b89fccd02d        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-node-5b47bb8bd6-vqrvb_thingsboard_3f25d857-1624-4d27-90a5-2c54c35747ee_1
    9a047136e01b        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-k4ncf_thingsboard_cdd283fc-d0a2-45b6-b533-00dd4d38e782_1
    c13f8513edf1        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-zvgrp_thingsboard_1fad5bb8-5793-48e7-8dcc-7cbaf0475192_1
    0fada7a20fe0        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-j756s_thingsboard_0be1997a-4d1b-4d01-a3ab-55d6e468f39d_1
    3e8bd573933b        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-5p9tg_thingsboard_87e80c57-0f84-43eb-bf24-13cc309e4cec_1
    936695bf38e1        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-web-ui-5958f67cc-4k4cj_thingsboard_6f3795e9-ded9-46b8-8067-b4afd63f2571_1
    15bc2206a101        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_ingress-nginx-controller-c4f944d4d-wcqxv_ingress-nginx_329aa6a7-2ee5-4747-b77d-82182d9a872f_1
    9fb9bcc3f42e        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-mqtt-transport-fb5f5d5cd-bs4tw_thingsboard_ef25b3b1-658e-4e4c-bd1c-a0ca2ab20ce4_1
    e5ff72d6497d        cdef7632a242                    "/usr/local/bin/kube…"   7 hours ago         Up 7 hours                              k8s_kube-proxy_kube-proxy-4fx4m_kube-system_61c86591-198c-4bcc-ac9a-756ba949c71c_1
    e8b88981ec37        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_zookeeper-547c6ffb99-bq42m_thingsboard_11a1e06d-bbf1-4b55-bab5-7d4e4b876f20_1
    2366f0c673fc        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-r2r5b_thingsboard_6ba2cc34-d6bb-4c14-96c8-0c11e20fd051_1
    dc3c77cd895b        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_tb-js-executor-56bbb8f446-9mmf2_thingsboard_97fc3fa7-ad20-4ffc-a34a-cda7aba93305_1
    7cef6c1b6fd8        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_coredns-f9fd979d6-ff45j_kube-system_df1c5b8b-26f5-48cc-a853-c050090e69ef_1
    7f3bf1c89eef        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_dashboard-metrics-scraper-7b59f7d4df-5dkwl_kubernetes-dashboard_3235eff1-3822-4138-8d0e-d45de95d3cbf_1
    cedd269cda38        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_coredns-f9fd979d6-k54r2_kube-system_9355c0e5-b8fc-4c3c-9644-89749adeee97_1
    1ff5b8974607        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_kubernetes-dashboard-5dbf55bd9d-bcc2v_kubernetes-dashboard_1e414605-d8c1-4918-8e9b-18bc2c01efe6_1
    38c2265588a8        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_storage-provisioner_kube-system_50005a87-62d2-45a0-a39e-c34af43d24c9_1
    47dfcf754624        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_kube-proxy-4fx4m_kube-system_61c86591-198c-4bcc-ac9a-756ba949c71c_1
    2410f48b0dcb        0369cf4303ff                    "etcd --advertise-cl…"   7 hours ago         Up 7 hours                              k8s_etcd_etcd-docker-desktop_kube-system_c7cc6a3c3118f127f5fd469ef69477e0_1
    8282e8feb792        a301be0cd44b                    "kube-apiserver --ad…"   7 hours ago         Up 7 hours                              k8s_kube-apiserver_kube-apiserver-docker-desktop_kube-system_2085f5be68201a12aeffb940f7ba4272_1
    a8d6bd3cc82a        9b60aca1d818                    "kube-controller-man…"   7 hours ago         Up 7 hours                              k8s_kube-controller-manager_kube-controller-manager-docker-desktop_kube-system_07d42b7bf3823b30f57219558fcb55e2_1
    acebbb6ddd18        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_kube-scheduler-docker-desktop_kube-system_ee4c94eb845abf1878fb3c4c489b1365_1
    d395721ce499        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_kube-controller-manager-docker-desktop_kube-system_07d42b7bf3823b30f57219558fcb55e2_1
    ff1cfd6ae1b2        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_kube-apiserver-docker-desktop_kube-system_2085f5be68201a12aeffb940f7ba4272_1
    2060020e4bc4        k8s.gcr.io/pause:3.2            "/pause"                 7 hours ago         Up 7 hours                              k8s_POD_etcd-docker-desktop_kube-system_c7cc6a3c3118f127f5fd469ef69477e0_1

    好多个 container 在跑,好壮观

    这时,你以为可以成功访问 ThingsBoard 主页吗?不行,真的不行,因为还差一个步骤,非常重要,那就是你的机器还没有 ingress ,建议你去好好读一读这个知识点。

    安装 Ingress Nginx

    # kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/cloud/deploy.yaml
    想办法把这个文件搞下来,因为这是部署 Ingress Nginx 的配置文件

    我提供一个备份: ingress-nginx.yaml,启动:

    # kubectl apply -f ingress-nginx.yaml
    namespace/ingress-nginx unchanged
    serviceaccount/ingress-nginx unchanged
    configmap/ingress-nginx-controller configured
    clusterrole.rbac.authorization.k8s.io/ingress-nginx unchanged
    clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx unchanged
    role.rbac.authorization.k8s.io/ingress-nginx unchanged
    rolebinding.rbac.authorization.k8s.io/ingress-nginx unchanged
    service/ingress-nginx-controller-admission unchanged
    service/ingress-nginx-controller unchanged
    deployment.apps/ingress-nginx-controller configured
    validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission configured
    serviceaccount/ingress-nginx-admission unchanged
    clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
    clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
    role.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
    rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
    job.batch/ingress-nginx-admission-create unchanged
    job.batch/ingress-nginx-admission-patch unchanged
    
    • 下载 ingress-nginx 镜像
    # docker pull k8s.gcr.io/ingress-nginx/controller:v0.41.2@sha256:1f4f402b9c14f3ae92b11ada1dfe9893a88f0faeb0b2f4b903e2c67a0c3bf0de

    因为系统提示,这个镜像无法下载,或这很慢,你需要手动执行。看看有没有成功:

    # kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --watch
    
    NAME                                       READY   STATUS      RESTARTS   AGE
    ingress-nginx-admission-create-sd5zj       0/1     Completed   0          16m
    ingress-nginx-admission-patch-pfjhp        0/1     Completed   2          16m
    ingress-nginx-controller-c4f944d4d-wcqxv   0/1     Running     0          16m
    
    ingress-nginx-controller-c4f944d4d-wcqxv   1/1     Running     0          16m
    • 查看本地是否已经成功监听 80 和 443 端口,如果存在,那就是跑通了
    netstat -na  |grep LIST
    
    tcp46      0      0  *.1883                 *.*                    LISTEN     
    tcp46      0      0  *.443                  *.*                    LISTEN     
    tcp46      0      0  *.80                   *.*                    LISTEN     
    
    • 查看 k8s dashboard 状态
      tb-in-k8s.png
    • ThingsBoard 登陆界面,出现太重要了
      tg-login.png
    • 成功登陆,且新建租户正常
      tb-tenant.png

    最后,不建议在本地跑 k8s,速度太慢了,不如跑 jar 来的方便,调试起来也不方便。开发环境用 mvn spring-boot:run,测试环境直接部署在 CentOS 或 Ubuntu 环境单机跑足够用了,大量数据采集,访问用户数量大,才可以试试 k8s 环境,欢迎大家留言讨论!

    本文所有内容都来自原创,思路开阔,敢想敢做,经过不懈努力,终于成功扩展 ThingsBoard 功能模块

    先来看一段视频,体验一下新增的功能,前端增加的菜单和功能演示。
    tb-v.mp4

    前言

    此次二次开发,主要是针对 ThingsBoard 新增功能模块,以报表功能为目的,提供一个可以独立与原有功能的 Report/报表 模块,咱们先这么来定义。就像 Device/设备、Asset/资产模块,增删改查必不可少,还需要兼容 ThingsBoard 原有操作习惯,还可以将 Report/报表 分配给特定的 Customer/客户。上图,这是开始的设想:
    tb1.png

    后端

    代码结构

    modified:   application/src/main/java/org/thingsboard/server/controller/BaseController.java
    new file:   application/src/main/java/org/thingsboard/server/controller/ReportController.java
    modified:   application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java
    modified:   application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java
    modified:   application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
    modified:   application/src/main/resources/thingsboard.yml
    new file:   common/dao-api/src/main/java/org/thingsboard/server/dao/report/ReportService.java
    modified:   common/data/src/main/java/org/thingsboard/server/common/data/CacheConstants.java
    modified:   common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java
    new file:   common/data/src/main/java/org/thingsboard/server/common/data/Report.java
    new file:   common/data/src/main/java/org/thingsboard/server/common/data/ReportInfo.java
    modified:   common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
    new file:   common/data/src/main/java/org/thingsboard/server/common/data/id/ReportId.java
    modified:   common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilterType.java
    new file:   common/data/src/main/java/org/thingsboard/server/common/data/query/ReportSearchQueryFilter.java
    new file:   common/data/src/main/java/org/thingsboard/server/common/data/query/ReportTypeFilter.java
    new file:   common/data/src/main/java/org/thingsboard/server/common/data/report/ReportSearchQuery.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractReportEntity.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/model/sql/ReportEntity.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/model/sql/ReportInfoEntity.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/report/ReportDao.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/report/ReportServiceImpl.java
    modified:   dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java
    modified:   dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/sql/report/JpaReportDao.java
    new file:   dao/src/main/java/org/thingsboard/server/dao/sql/report/ReportRepository.java
    modified:   pom.xml

    根据 git 提供的log,看出来新增文件比修改文件多,也是此次二次开发的难点所在。

    • 新增文件:新增的文件主要以扩展功能模块为主,大概是这样:POJO(DTO,ID),Entity,Repository,Dao,Service/Impl,Controller,基本都是依葫芦画瓢;
    • 修改文件:因为要达到 ThingsBoard 原有的一些功能体验,势必要满足其实现逻辑,那就是找到所有的 Device 功能模块的做法,在所有需要的地方增加 Report 功能,无非就是一些新增枚举值,方法调用,新增 case 判断;

    这个开发过程中,我发现,频繁读取一些 API,且都是需要数据库交互,如果用户数量大,不是一个好方法,这里举一个例子:

    • 获取实体类型频繁数据库交互
      types.png

    调用后台 API 为: /api/report/types,追查代码发现其实是一次 SELECT,瞬间尴尬了

    @Query("SELECT DISTINCT d.type FROM ReportEntity d WHERE d.tenantId = :tenantId")
    List<String> findTenantReportTypes(@Param("tenantId") UUID tenantId);
    • WEB API,大概就是把 device 都替换成了 report,其他逻辑上没有做更改,为了配合前端的调用,这些都是必不可少的内容。因为用 device 衍生过来,把 cridentail 相关内容删除了。
      tb3.png

    数据表

    CREATE TABLE public.report
    (
        id uuid NOT NULL,
        created_time bigint NOT NULL,
        additional_info character varying COLLATE pg_catalog."default",
        customer_id uuid,
        type character varying(255) COLLATE pg_catalog."default",
        name character varying(255) COLLATE pg_catalog."default",
        label character varying(255) COLLATE pg_catalog."default",
        search_text character varying(255) COLLATE pg_catalog."default",
        tenant_id uuid,
        CONSTRAINT report_pkey PRIMARY KEY (id),
        CONSTRAINT report_name_unq_key UNIQUE (tenant_id, name)
    )
    • 如果你观察仔细,发现跟 device 表几乎一样,那是因为我们以 device 为原型做的二次开发。开发自己功能时,表的定义请随意啊。不过,name, type, search_text, id, customer_id, tenant_id, create_time 都是不能少的,因为框架业务逻辑有代码实现一些功能;
    • 建议增加几个不影响 ThingsBoard 框架工作的“扩展字段”,也可以直接使用 additional_info 来存储自己的数据,这个字段最长可以有 1G,足够放你需要的结构化或非结构化数据;类似:
    {
        "hello": "world",
        "thingsboard": "iot",
        "company": "yiqisoft",
        "location": "shanghai",
        "protocol": ["coap", "mqtt", "http"]
    }
    • 自由业务逻辑,针对“扩展字段”的操作,请随意,数据频繁修改的还是用自己的业务表,不要混为一谈。

    业务逻辑实现

    tb2.png
    对于自己的业务逻辑开发方面,建议不要改动 ThingsBoard 的代码结构,可以使用外挂一个 jar,来独立实现业务功能,这个具体要看业务复杂度,是不是需要与 ThingsBoard 耦合,可以查看前期我们发布的文章:如何无缝扩展 ThingsBoard 功能?原来二次开发如此简单!如何无缝扩展 ThingsBoard 功能?原来二次开发如此简单!【续】

    前端

    代码结构

    modified:   ui-ngx/src/app/core/http/entity.service.ts
    new file:   ui-ngx/src/app/core/http/report.service.ts
    modified:   ui-ngx/src/app/core/services/menu.service.ts
    modified:   ui-ngx/src/app/modules/home/components/widget/lib/entities-hierarchy-widget.models.ts
    modified:   ui-ngx/src/app/modules/home/dialogs/add-entities-to-customer-dialog.component.ts
    modified:   ui-ngx/src/app/modules/home/dialogs/assign-to-customer-dialog.component.ts
    modified:   ui-ngx/src/app/modules/home/dialogs/home-dialogs.service.ts
    modified:   ui-ngx/src/app/modules/home/pages/customer/customer-routing.module.ts
    modified:   ui-ngx/src/app/modules/home/pages/customer/customer.component.html
    modified:   ui-ngx/src/app/modules/home/pages/customer/customers-table-config.resolver.ts
    modified:   ui-ngx/src/app/modules/home/pages/home-pages.module.ts
    new file:   ui-ngx/src/app/modules/home/pages/report/report-routing.module.ts
    new file:   ui-ngx/src/app/modules/home/pages/report/report-table-header.component.html
    new file:   ui-ngx/src/app/modules/home/pages/report/report-table-header.component.scss
    new file:   ui-ngx/src/app/modules/home/pages/report/report-table-header.component.ts
    new file:   ui-ngx/src/app/modules/home/pages/report/report-tabs.component.html
    new file:   ui-ngx/src/app/modules/home/pages/report/report-tabs.component.ts
    new file:   ui-ngx/src/app/modules/home/pages/report/report.component.html
    new file:   ui-ngx/src/app/modules/home/pages/report/report.component.scss
    new file:   ui-ngx/src/app/modules/home/pages/report/report.component.ts
    new file:   ui-ngx/src/app/modules/home/pages/report/report.module.ts
    new file:   ui-ngx/src/app/modules/home/pages/report/reports-table-config.resolver.ts
    modified:   ui-ngx/src/app/shared/components/entity/entity-autocomplete.component.ts
    modified:   ui-ngx/src/app/shared/components/entity/entity-subtype-autocomplete.component.ts
    modified:   ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.ts
    modified:   ui-ngx/src/app/shared/components/entity/entity-subtype-select.component.ts
    modified:   ui-ngx/src/app/shared/components/footer.component.html
    modified:   ui-ngx/src/app/shared/models/alias.models.ts
    modified:   ui-ngx/src/app/shared/models/entity-type.models.ts
    new file:   ui-ngx/src/app/shared/models/id/report-id.ts
    new file:   ui-ngx/src/app/shared/models/report.models.ts
    modified:   ui-ngx/src/assets/locale/locale.constant-en_US.json
    modified:   ui-ngx/src/assets/locale/locale.constant-zh_CN.json
    modified:   ui-ngx/src/assets/logo_title_white.svg
    modified:   ui-ngx/src/environments/environment.prod.ts
    modified:   ui-ngx/src/environments/environment.ts
    modified:   ui-ngx/src/index.html
    new file:   ui-ngx/src/yiqisoft.ico
    • 先复制一份 ui-ngx/src/app/modules/home/pages/device 到 ui-ngx/src/app/modules/home/pages/report,就是组件要完整,文件名都改掉,内部都是替换操作: Device -> Report, device -> report, DEVICE -> REPORT,这样我们的 ReportModule 就做好了;
    • 在 home-pages.module.ts 载入 ReportModule ;
    • 在 ui-ngx/src/app/core/services/menu.service.ts 增加需要的菜单;
    • 根据 report 目录里面的内容,需要从 device 功能模块复制一些组件和 service,挺多的,自己慢慢找,也算是熟悉一下前端代码;
    • 汉化,就是修改 ui-ngx/src/assets/locale/ 目录下相应的语言包,很容易;

    功能扩展过程

    前期,我们发布了文章,如何进行 ThingsBoard 前端二次开发?超强 Angular 框架帮你忙。,介绍如果用 Angular 二次开发的要点,具体看开发者对于 Angular 框架掌握程度。

    功能扩展建议

    • 像上面的实体类型获取,增加功能特别不容易,因为代码实现是通过枚举值来 switch/case 来判断,那么新增功能模块时,需要改动太大了,如果能够独立到每个功能模块的组件中,那就方便多了。但是,前端代码就会有很多重复。为了扩展 REPORT,必须要找到所有的 case,上代码:
        switch (entity.id.entityType as EntityType | string) {
          case 'function':
            materialIcon = 'functions';
            break;
          case EntityType.DEVICE:
            materialIcon = 'devices_other';
            break;
          case EntityType.REPORT:
            materialIcon = 'equalizer';
            break;
          case EntityType.ASSET:
            materialIcon = 'domain';
            break;
        }
    • 更改 LOGO,需要使用工具做一个 svg 矢量图,替换 ui-ngx/src/assets/logo_title_white.svg 即可;
    • 更改 Swagger 显示内容需要改 thingsboard.yml;

    欢迎大家一起来加入 ThingsBoard 讨论,可以在下方留言给作者。其实,我是最不建议在 ThingsBoard 上改动,我崇尚无缝扩展,但是太难了,所以才有了本文的发表,把自己的业务融入进去是一次尝试。当然,有能力的朋友可以自己独立做业务系统,对于简单物联网应用,何必重复制造轮子呢?