GithubHelp home page GithubHelp logo

i-things / ithings Goto Github PK

View Code? Open in Web Editor NEW
374.0 13.0 68.0 70.55 MB

物联网设备接入平台

Home Page: http://ithings.net.cn/

License: GNU Affero General Public License v3.0

Shell 0.01% Go 99.66% Dockerfile 0.06% Makefile 0.19% Batchfile 0.07%
ant-design go golang react things chatgpt aiot

ithings's Introduction

物联网云平台ithings

iThings是一个基于golang开发的轻量级云原生微服务物联网平台.

定位于:

  • 高性能 -- 使用golang编写,选用高性能组件(emqx,nats,tdengine),基于gozero微服务框架高性能的同时保证服务的稳定性
  • 云原生易拓展 -- 一套代码同时支持k8s,docker,微服务及单体模式部署,便于业务从单体到微服务的切换
  • 易部署 -- 一键安装所有依赖,一键运行iThings
  • 易集成 -- 可以通过http,grpc,甚至直接将iThings作为包集成进自己系统

git地址:

产品架构

iThings物联网平台提供跨不同设备和数据源的通用接入及管理平台,在整个物联网架构中起到承上启下的中介作用, 联动感知层及应用层之间的所有交互——向下连接、管理物联网设备端并完成感知数据的归集与存储, 向上为应用开发商与系统集成商提供应用开发的统一数据接口及共性模块工具。
应用厂商可以通过http,grpc,及golang包引入的方式快速集成进自己的系统中,迅速获取物联网平台的能力,轻量而高效.

产品价值

平台价值 描述
拓展能力强 公司发展有不同的阶段,应用场景也有不同的需要,iThings同时支持单体和微服务便于开发者不需要维护两套代码同时单体不足以满足公司需要时也可以很便捷的切换为微服务架构
高性能 使用golang开发,依赖的第三方服务很少,对于性能要求不高的场景甚至可以部署到低性能的arm上
数据价值 私有化部署,所有数据都可以自己去管理,不用担心公有云停服及收费高的问题
解决方案底座 可做为行业解决方案的数字底座,支持多行业解决方案共用同一个物联网平台底座,为企业沉淀更多行业经验和产品方案。

产品特性

  • 设备接入:通过行业标准物联网协议(MQTT、CoAP 和 HTTP)实现海量设备连接,也可以通过规则引擎接入自定义协议。
  • 远程控制:使用http api可以实现服务器对设备的精准控制和设备主动向服务器发送请求通知。
  • 物模型:支持标准物模型,有效管理设备的属性,事件及行为。
  • RBAC权限:权限控制采用 RBAC,基于角色的访问控制。封装完善的用户、角色、菜单等基础权限功能。
  • 应用支撑:提供http,grpc或golang直接导入包的形式将数据流转至业务层面,屏蔽了物联网层面的复杂特性,让企业专注业务应用开发,缩短物联网解决方案的上市周期,为企业节省大量研发时间和成本。
  • 自主可控:私有云、公有云、边缘部署.
  • 快速开发及维护: 提供设备云端调试日志,设备本地日志,在线设备调试 快速开发及调试问题

产品功能

功能 描述
后台管理 独立后台,提供用户管理,角色管理,菜单管理
设备管理 包含设备信息维护、数据收集等基础功能,支持设备参数配置、模型配置、在线调试等功能。
产品管理 支持产品管理,物模型管理,远程配置管理
设备分组 支持设备最多三级分组
网关子设备 完整网关子设备功能

技术架构

后端架构

技术栈

  1. 微服务框架:go-zero
  2. 高性能缓存:redis
  3. 高性能消息队列:nats
  4. 关系型数据库:mysql(请使用mariaDB或mysql5.7)或pgsql
  5. 微服务注册中心(单体可不使用):etcd
  6. 云原生轻量级对象存储:minio
  7. 开源、高性能、云原生,极简的时序数据处理平台:tdengine
  8. 大规模可弹性伸缩的云原生分布式物联网MQTT消息服务器:emqx

代码结构

src模块简介、编译及启动方式.readme.md

- deploy #部署时 相关配置
  - conf
    - emqx #mtqq组件 相关配置
      - data
        - loaded_plugins
      - etc
        - plugins
          - emqx.conf #mtqq组件 主要服务配置文件
          - emqx_auth_http.conf #mtqq组件 鉴权服务配置文件
    - ithings #本项目服务 相关配置
      - apisvr
        - etc #部署时 各服务 配置文件
          - api.yaml #api网关接口代理模块配置
          - dd.yaml #设备数据处理模块配置
          - di.yaml #设备交互模块配置
          - dm.yaml #设备管理模块配置
          - sys.yaml #系统管理模块配置
    - mysql #本项目SQL文件
      - sql
        - dmsvr.sql #设备管理模块SQL
        - rulesvr.sql #协议规则引擎模块SQL
        - syssvr.sql #系统管理模块SQL
    - nats #nats组件 相关配置
      - nats-server.conf # #nats配置文件

- doc #项目文档
  - assets #一些逻辑流程图、架构图、二维码
  - v2 #v2版本架构设计思路

- shared #公共服务、DTO、Client
  - clients #mqtt/nats/TDengine client
  - conf #配置文件内 部分对象的 DTO
  - def #常量、结构体 通用定义
  - devices #此负责提供 和设备相关的 公用的操作函数
  - domain #此包用于封装 跨服务共享的 领域对象
    - application #此包负责定义 应用层推送的 结构体
    - deviceAuth
    - schema #此包负责 物模型定义及相关逻辑
  - errors #程序错误对象、错误码的定义
  - events #此包负责提供事件的封装及解包(如topic、常量、结构体、封解方法)
  - oss #对象存储SDK
  - proto #公共proto定义
  - result #apisvr网关模块 响应结果处理 的封装
  - store
  - third #第三方SDK对接
  - traces #链路追踪方法封装
  - users #jwt方法封装
  - utils #工具类函数封装
  - verify #验证码函数封装

- src #项目主要代码(go-zero rest)
  - apisvr #api网关接口代理模块
    - etc #单体部署 运行时 各服务 配置文件
      - api.yaml #api网关接口代理模块配置
      - dd.yaml #设备数据处理模块配置
      - di.yaml #设备交互模块配置
      - dm.yaml #设备管理模块配置
      - sys.yaml #系统管理模块配置
    - apidirect
      - direct.go #加载配置、协程启动dd服务、构造单例上下文(含根据配置判断连接其他子服务)
  - ddsvr #设备数据处理模块(go-zero rest)
    - etc
      - dd.yaml #独立部署 运行时 当前服务 配置文件
    - dddirect
      - direct.go #加载配置、构造单例上下文、注册消费者Handle
  - disvr #设备交互模块(go-zero rpc)
    - etc
      - di.yaml #独立部署 运行时 当前服务 配置文件
    - didirect
      - direct.go #加载配置、构造单例上下文、注册消费者Handle
  - dmsvr #设备管理模块(go-zero rpc)
    - etc
      - dm.yaml #独立部署 运行时 当前服务 配置文件
    - dmdirect
      - direct.go #加载配置、构造单例上下文
  - rulesvr #协议规则引擎模块(go-zero rpc)
    - etc
      - rule.yaml #独立部署 运行时 当前服务 配置文件
    - ruledirect
      - direct.go #加载配置、构造单例上下文、注册消费者Handle
  - syssvr #系统管理模块(go-zero rpc)
    - etc
      - sys.yaml #独立部署 运行时 当前服务 配置文件
    - sysdirect
      - direct.go #加载配置、构造单例上下文

- tests #单元测试用例

前端架构

技术栈

  1. 用于构建用户界面的 JavaScript 库:react
  2. 企业级设计组件:ant design
  3. 一套高质量可靠的 React Hooks库:ahooks

贡献者

感谢所有已经做出贡献的人!

后端

前端

社区

  • 微信(加我拉微信群): godLei6 (需备注“来自github”)
  • QQ群(需备注“来自github”): 776725046
  • 官网
  • 时刻招募相信分布式办公的你
  • 参与方式: 先搭建环境并运行起iThings, 社区分配一两个简单功能开始入手
  • 微信二维码

赞赏

  • 如果iThings对你有帮助或者有启发,欢迎赞赏,这是对我们的认可及动力

收藏

ithings's People

Contributors

cooclsee avatar fish2016 avatar gleke avatar godlei6 avatar hehaokun2814 avatar kevwan avatar lbs0019873800lbs avatar lczz89 avatar rbtyang avatar suixinio avatar wwhai avatar zhuangpengli avatar znonymous29 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ithings's Issues

ithings的post接口不支持带XX.XX的json名字规则的数据。

向apisvr发送POST json数据时,如下json的数据格式会出现解析异常。
{ "api.apiDebug" : "1", "api.secret" : "035c73f7-bb6b-4889-a715-d9eb2d1925cc", "ffmpeg.bin" : "/usr/local/bin/ffmpeg", "ffmpeg.cmd" : "%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s", "ffmpeg.log" : "./ffmpeg/ffmpeg.log", "general.mediaServerId" : "your_server_id", "general.addMuteAudio" : "1", "general.enableVhost" : "1", "general.flowThreshold" : "1024", }
Uploading d68bdf465cb3e565c4eab4de77dfc91.png…
带点的json名无法正常被解析。

测试示例见附件
post接收json数据异常.txt

前后端自动打包

  1. 前端实现打tag的时候自动cicd生成release包
  2. 后端实现自动部署
  3. 后端实现打tag的时候生成docker-compose release包

后端-设备调试日志

设备日志主要用于平台远程查看设备运行日志,平台可通过下发消息,通知设备进行日志上报,日志级别包括错误、警告、信息和调试。

几个建议

  1. todolist 用起来,可以试试 project 功能
  2. git commit 规范一下
  3. github actions CI、CD用起来

后端-ota升级

$ota/up/report/${productID}/${deviceName}   设备上报版本号(上行)
$ota/up/progress/${productID}/${deviceName}   设备上报下载进度(上行)
$ota/down/update/${productID}/${deviceName}   服务器端推送ota信息(下行)

apisvr模块启动之后,通过mqttx发送测试消息报表不存在,是否因为设备离线,未生成表导致?

版本:master
报错信息

2023-02-22T18:44:19.963+08:00    info   sql taosQuery: insert into `device_property_25Mjq9jn0je_Test-Device_test` (ts, param) values ('2023-02-22T18:44:19.959+08:00',1);       duration=0.0ms caller=taosRestful/connection.go:180
2023-02-22T18:44:19.963+08:00    error  deviceMsgEvent.(*ThingLogic).HandlePropertyReport.InsertPropertyData err={"code":100008,"msg":"数据库错误","details":["SchemaDataRepo.InsertPropertiesData.InsertPropertyData identifier:test param:1 err:[0x2603] Table does not exist"]}      caller=deviceMsgEvent/thing.go:97       trace=ec6cf1ad8c1f9fea48e762b9c40ed616  span=c9befb34de400012
2023-02-22T18:44:19.965+08:00    info   sql taosQuery: insert into `device_hublog_25Mjq9jn0je_Test-Device` using `model_common_hublog` tags('25Mjq9jn0je','Test-Device')(`ts`, `content`, `topic`, `action`, `requestID`, `trance_id`, `result_type`) values ('2023-02-22T18:44:19.959+08:00','{
    "method": "report",
    "clientToken": "afwegafeegfa",
    "params": {
      "test": 1
    }
}
','$thing/up/property/25Mjq9jn0je/Test-Device','property','afwegafeegfa','ec6cf1ad8c1f9fea48e762b9c40ed616',100008);    duration=0.0ms  caller=taosRestful/connection.go:180
2023-02-22T18:44:19.965+08:00    info   DeviceMsgHandle.deviceResp.PublishToDev msg:{"DeviceNames":"","Payload":"{\"method\":\"reportReply\",\"clientToken\":\"afwegafeegfa\",\"timestamp\":1677062659963,\"code\":100008,\"status\":\"数据库错误\"}","ProductID":"","Timestamp":"2023-02-22T18:44:19.963140843+08:00","Topic":"$thing/down/property/25Mjq9jn0je/Test-Device"}  caller=deviceMsgEvent/deviceMsg.go:92   trace=ec6cf1ad8c1f9fea48e762b9c40ed616  span=c9befb34de400012
2023-02-22T18:44:19.965+08:00    info   deviceMsgEvent.(*DeviceMsgHandle).Thing req:{"DeviceNames":"Test-Device","Payload":"{                     \n    \"method\": \"report\",            \n    \"clientToken\": \"afwegafeegfa\",   \n    \"params\": { \n      \"test\": 1\n    }\n}\n","ProductID":"25Mjq9jn0je","Timestamp":"2023-02-22T18:44:19.959+08:00","Topic":"$thing/up/property/25Mjq9jn0je/Test-Device"} resp:{"DeviceNames":"","Payload":"{\"method\":\"reportReply\",\"clientToken\":\"afwegafeegfa\",\"timestamp\":1677062659963,\"code\":100008,\"status\":\"数据库错误\"}","ProductID":"","Timestamp":"2023-02-22T18:44:19.963140843+08:00","Topic":"$thing/down/property/25Mjq9jn0je/Test-Device"} err:{"code":100008,"msg":"数据库错误","details":["SchemaDataRepo.InsertPropertiesData.InsertPropertyData identifier:test param:1 err:[0x2603] Table does not exist"]}    caller=deviceMsgEvent/deviceMsg.go:39   trace=ec6cf1ad8c1f9fea48e762b9c40ed616  span=c9befb34de400012
2023-02-22T18:44:19.965+08:00    error  nats subscription|subject:device.up.thing.25Mjq9jn0je.Test-Device,body:{"timestamp":1677062659959,"productID":"25Mjq9jn0je","deviceName":"Test-Device","topic":"$thing/up/property/25Mjq9jn0je/Test-Device","payload":"eyAgICAgICAgICAgICAgICAgICAgIAogICAgIm1ldGhvZCI6ICJyZXBvcnQiLCAgICAgICAgICAgIAogICAgImNsaWVudFRva2VuIjogImFmd2VnYWZlZWdmYSIsICAgCiAgICAicGFyYW1zIjogeyAKICAgICAgInRlc3QiOiAxCiAgICB9Cn0K"},err:{"code":100008,"msg":"数据库错误","details":["SchemaDataRepo.InsertPropertiesData.InsertPropertyData identifier:test param:1 err:[0x2603] Table does not exist"]} duration=0.0ms  caller=events/nats.go:28        trace=ec6cf1ad8c1f9fea48e762b9c40ed616  span=c9befb34de400012

[优化] 在数据量大的时候获取最新的物模型数据会比较慢

问题原因:
tdengine在针对select * 最新数据的时候优化不够好,后续版本会优化
td优化方案:切换成last_row,并执行: alter database ithings cachemodel 'both' cachesize 200;
打开td缓存: 测试后查询速度0.036秒

解决方案:

  1. 切换为并发查询(已合并master),原来页面需要1分钟现在893ms
  2. 修改为last_row方案(但是td这边后续会有改动)不采取
  3. 将最新数据缓存到Redis上 -- 后续安排

需要做第三点

设备管理-设备-批量导入

  • 支持 校验文件格式(仅csv, <=700KB, <=1k条)
  • 支持 不同产品混合导入
  • 支持 导出失败清单,重新导入

后端-设备远程配置

功能概述
设备使用场景中,对于需要更新系统参数(如:设备的 IP、端口号和串口参数等)的设备,可采用远程配置功能对设备系统参数进行更新。

功能详情
设备远程配置分为物联网平台主动下发和设备端主动请求两种配置更新方式。对于同一产品下所有设备均需更新配置的场景,可采用物联网平台主动下发的形式,将配置信息通过远程配置 Topic 下发到同一产品下的所有设备中。对于部分设备更新配置信息的场景,可采用设备端主动请求远程配置 Topic 的方式来完成。

设备主动请求配置信息

远程配置请求 Topic:$config/up/get/${productid}/${devicename}
远程配置订阅回复 Topic:$config/down/get/${productid}/${devicename}

物联网平台推送配置信息给设备端

远程配置订阅通知 Topic:$config/down/push/${productid}

后台登录安全控制(默认情况下不需要验证码)

默认情况下不需要验证码

需要进行以下维度的安全控制:

  1. 用户连续输错密码x次 -- 需要输入验证码
  2. 用户连续输错密码y次 -- 封禁账号登录n 分钟
  3. ip x小时内累计输错密码y次 -- 封禁ip登录 x分钟

latest image run with error: "userName not right"

latest image run error

./init.db.sh  
docker-compose logs --tail 100 ithings

ithings | 2023-04-03T15:51:52.537+08:00 info auth.(*LoginLogic).Login req=&{Username:ddsvr Password:iThings ClientID:dd.rpc/e4756ba1-088c-c289-8853-845b49d3e3ca Ip:172.19.0.8 Certificate:} caller
=auth/loginLogic.go:31 trace=13e6e546367c3a04d4e00cfc93f8c582 span=51c6ef7dc8b2d497
ithings | 2023-04-03T15:51:52.538+08:00 info deviceauth.(*LoginAuthLogic).LoginAuth req=username:"ddsvr" password:"iThings" clientID:"dd.rpc/e4756ba1-088c-c289-8853-845b49d3e3ca" ip:"172.19.0.8"c
aller=deviceauth/loginAuthLogic.go:103 trace=13e6e546367c3a04d4e00cfc93f8c582 span=51c6ef7dc8b2d497
ithings | 2023-04-03T15:51:52.538+08:00 error auth.(*LoginLogic).Login.rpc.ManageDevice req=&{ddsvr iThings dd.rpc/e4756ba1-088c-c289-8853-845b49d3e3ca 172.19.0.8 } err={"code":100006,"msg":"参数
错误","details":["userName not right"]} caller=auth/loginLogic.go:52 trace=13e6e546367c3a04d4e00cfc93f8c582 span=51c6ef7dc8b2d497
ithings | 2023-04-03T15:51:52.538+08:00 error 【http handle err】router:/api/v1/things/device/auth/login err: {"code":100006,"msg":"参数错误","details":["userName not right"]} caller=result/
httpResult.go:29 trace=13e6e546367c3a04d4e00cfc93f8c582 span=51c6ef7dc8b2d497
ithings | 2023-04-03T15:51:52.538+08:00 info [HTTP] 400 - POST /api/v1/things/device/auth/login - 172.19.0.7:41456 - duration=0.7ms caller=handler/loghandler.go:160 trace=13e6e546
367c3a04d4e00cfc93f8c582 span=51c6ef7dc8b2d497
ithings | 2023-04-03T15:51:52.538+08:00 info mqtt client connect attempt broker:tcp://172.19.0.7:1883 caller=clients/mqtt.go:45
ithings | 2023-04-03T15:51:52.539+08:00 info auth.(*LoginLogic).Login req=&{Username:ddsvr Password:iThings ClientID:dd.rpc/e4756ba1-088c-c289-8853-845b49d3e3ca Ip:172.19.0.8 Certificate:} caller
=auth/loginLogic.go:31 trace=beff4ceedfdfaa02e847c9efd898a262 span=1a3d4901d4b72dc3
ithings | 2023-04-03T15:51:52.539+08:00 info deviceauth.(*LoginAuthLogic).LoginAuth req=username:"ddsvr" password:"iThings" clientID:"dd.rpc/e4756ba1-088c-c289-8853-845b49d3e3ca" ip:"172.19.0.8"c
aller=deviceauth/loginAuthLogic.go:103 trace=beff4ceedfdfaa02e847c9efd898a262 span=1a3d4901d4b72dc3
ithings | 2023-04-03T15:51:52.539+08:00 info [HTTP] 400 - POST /api/v1/things/device/auth/login - 172.19.0.7:43627 - duration=0.3ms caller=handler/loghandler.go:160 trace=beff4cee
dfdfaa02e847c9efd898a262 span=1a3d4901d4b72dc3
ithings | 2023-04-03T15:51:52.539+08:00 error auth.(*LoginLogic).Login.rpc.ManageDevice req=&{ddsvr iThings dd.rpc/e4756ba1-088c-c289-8853-845b49d3e3ca 172.19.0.8 } err={"code":100006,"msg":"参数
错误","details":["userName not right"]} caller=auth/loginLogic.go:52 trace=beff4ceedfdfaa02e847c9efd898a262 span=1a3d4901d4b72dc3
ithings | 2023-04-03T15:51:52.539+08:00 error 【http handle err】router:/api/v1/things/device/auth/login err: {"code":100006,"msg":"参数错误","details":["userName not right"]} caller=result/
httpResult.go:29 trace=beff4ceedfdfaa02e847c9efd898a262 span=1a3d4901d4b72dc3
ithings | 2023-04-03T15:51:56.534+08:00 info mqtt Connect failure caller=clients/mqtt.go:54
ithings | 2023-04-03T15:51:56.534+08:00 error NewDevClient errmqtt client connect failure caller=svc/serviceContext.go:20

image version:
docker pull ghcr.io/i4de/ithings:sha256-daf2e7b10b71be69584c44808099437c29ce915a5cd70e773e0428daad2e055b.sig

后端-设备影子

设备影子充当中介,支持设备和用户应用程序查看和更新设备状态。设备、用户应用程序、设备影子三者之间通过两个特殊的 Topic 来实现通信:

$shadow/operation/up/${productId}/${deviceName}:用于发布(上行)消息,可实现对设备影子数据的 get/update 操作。
$shadow/operation/down/${productId}/${deviceName}:用于订阅(下行)消息,影子服务端通过此 Topic 发送应答和推送消息。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.