AI 时代的万物互联底座。以「物」为本体的轻量级 AIoT 平台 — 实现万物智能只需三步:① 构建物 ② 通过驱动更新实时数据 ③ 剩下的交给 AI。
项目状态:早期开发阶段(v0.x)。核心平台(物模型、告警、事件、AI Agent、MCP)可用; 部分协议驱动仍在开发中,API 在 1.0 前可能有破坏性变更。欢迎试用与反馈。
官方网站: https://tinyiothub.com
仓库地址: https://github.com/Grong/tinyiothub
Docker Hub: https://hub.docker.com/r/grong/tinyiothub
设备接入
- 物本体模型:设备、空间、产线统一为层级化「物」,属性/事件/操作 + 知识文档
- 协议支持:MQTT 可用;Modbus RTU/TCP、ONVIF、SNMP 驱动开发中(驱动框架与 SDK 已就绪)
- AI 驱动匹配(实验性):描述设备类型,辅助匹配或生成驱动代码
- 物模板:JSON 模板一键创建,支持 DTDL / WoT 模型导入与 DTDL 导出
智能运维
- L0-L3 分级自愈引擎:system/device/task 三级探针,自动故障检测与恢复
- 自治运维(Thing Agent Loop):AI 被设备事件/定时巡检/用户指令唤醒,查本体、做决策、经三态策略门(off/diagnose/act)自主操作设备,行动后回读验证并留全量审计
- 规则引擎:阈值、范围、变化、持续时间、组合五种条件类型
- 心跳探针:定期自检网关与子设备,提前发现隐患;诊断结论自动转交自治 Loop 处置
- Cron 定时任务:Workspace 隔离,执行记录与统计
AI 原生
- 自然语言交互:用日常语言配置设备、查询状态、排查故障
- MCP Server:内嵌 Model Context Protocol 服务,Claude Desktop、Cursor 直接连接
- A2UI 聊天界面:SSE 流式对话,Agent 技能调用
- 设备自发现:AI 辅助识别设备类型并推荐驱动
部署灵活
- 单进程部署:~80MB 内存占用,无需外部数据库
- SQLite 存储:零依赖,自动迁移
- 开源 MIT 协议:可私有化部署,可商用
- Lit 3 前端:Web Components,轻量快速
tinyiothub/
├── apps/ # 可部署二进制
│ ├── cloud/ # relay:全部行为(domains/ 按域分模块)+ 组合根
│ │ ├── src/
│ │ │ └── domains/ # thing/auth/user/tenant/event/alarm/driver/notify/agent/mcp/admin
│ │ └── templates/ # 技能模板
│ ├── edge/ # 边缘网关
│ ├── marketplace/ # 市场服务(驱动/物模板市场)
│ └── cli/ # 命令行工具
├── crates/ # 能力库 Crate(relay 范式:只提供能力,不做编排)
│ ├── core/ # 纯值类型(零 I/O、零 API 语义)
│ ├── db/ # 全部 SQL:Db 门面 + 领域平铺文件(行类型+查询函数+impl Db 委托)+ migration
10000
s/(baseline + DDL-only)
│ ├── runtime/ # EventBus, DataServer, 驱动框架, plugin loader
│ ├── web/ # HTTP 基础设施(中间件、ApiResponseBuilder)
│ ├── scheduler/ # Cron 引擎
│ ├── llm/ # LLM provider 契约
│ ├── memory/ # Agent 记忆引擎(纯逻辑)
│ ├── policy/ # 策略门评估(纯逻辑)
│ ├── skills/ # 技能/信任引擎
│ ├── agent/ # Agent 共性能力运行时(loop/pool/tools/session/prompt,零 axum/零 sqlx)
│ ├── authn/ # 认证机制(JWT/SSE token/密码哈希,纯机制)
│ ├── plugin-sdk/ # 驱动开发 SDK(ABI 契约)
│ └── macros/ # 过程宏
├── drivers/ # 动态驱动 stub(cdylib,不在 workspace 内)
├── web/ # Lit 3 前端应用 (Web Components)
│ ├── src/ # 源代码
│ │ ├── ui/ # Lit 组件、页面、聊天/A2UI
│ │ ├── api/ # API 客户端
│ │ ├── i18n/ # 国际化
│ │ ├── styles/ # CSS 样式
│ │ └── stores/ # nanostore 状态管理
│ ├── package.json # Node.js 项目配置
│ └── vite.config.ts # Vite 构建配置
├── examples/ # 示例项目
│ ├── example-plugin/ # 插件示例
│ └── bacnet-driver/ # BACnet 驱动示例
├── vendor/ # 第三方依赖(本地 fork,如 onvif-rs)
├── scripts/ # 工具脚本
├── deploy/ # Docker 部署(docker-compose、边缘镜像)
├── docs/ # 项目文档
└── skills/ # AI prompts / skills
注意:本项目采用 relay 范式(buzz-relay 模型):apps/cloud 拥有全部行为,crates/ 为互不惊扰的能力库,依赖方向 apps/* → crates/* → core 单向不可逆。详细架构见 AGENTS.md。
后端:
- Rust: 1.85+ (2024 Edition)
- 操作系统: Linux, Windows(HarmonyOS 支持实验性)
- 数据库: SQLite (内置)
- 网络: MQTT Broker (可选)
前端:
- Node.js: 18+
- pnpm: 8+ (推荐包管理器)
- 浏览器: Chrome, Firefox, Safari, Edge
后端:
cd apps/cloud
cargo run前端:
cd web
pnpm install
pnpm dev构建:
# 前端静态资源 + 后端发布构建(仓库根目录)
cd web && pnpm build && cd ..
cargo build --release -p tinyiothub-cloud
# 或:just build(后端 release);容器构建见 Dockerfile运行:
cd apps/cloud
.\target\release\tinyiothub.exe # Windows
./target/release/tinyiothub # Linux/macOS优势:
- ✅ 单进程部署,无需 Node.js
- ✅ 内存占用低(~80MB vs ~200MB)
- ✅ 启动快速(<2s vs ~5s)
- ✅ 支持动态路由
Docker 部署见 deploy/docker/README.md。
cd web
# 安装依赖
pnpm install
# 开发运行
pnpm dev
# 构建生产版本
pnpm build后端配置文件位于仓库根目录 app_settings.toml:
# app_settings.toml 示例
[server]
host = "0.0.0.0"
port = 3002
[database]
url = "tinyiothub.db"
auto_migrate = true
[mqtt.primary]
host = "192.168.1.124"
port = 1883
username = "admin"
password = "password"
[security.jwt]
secret = "your-secret-key-must-be-at-least-32-characters-long"
expiration_secs = 10800 # 3 hours前端开发服务器代理配置位于 web/vite.config.ts:
server: {
port: 5173,
proxy: {
'/api': 'http://localhost:3002'
}
}启动后访问以下地址:
- Web 管理界面: http://localhost:5173/ (前端开发服务器)
- 后端 API: http://localhost:3002/api/v1/
- 健康检查: http://localhost:3002/health(返回纯文本 OK)
本项目严格遵循统一的API开发规范,确保前后端数据对接的一致性。
所有API端点必须返回以下格式:
{
"code": 0, // 0表示成功,非0表示错误
"msg": "", // 错误信息,成功时为空字符串
"result": T | null // 实际数据,错误时为null
}// ✅ 正确的API函数签名
async fn list_devices(
Query(params): Query<DeviceQuery>,
State(state): State<AppState>,
) -> Json<ApiResponse<Vec<Device>>> {
// 业务逻辑
let devices = get_devices(¶ms).await?;
ApiResponseBuilder::success(devices)
}
// 使用统一的响应构建器
use tinyiothub_web::response::ApiResponseBuilder;
// 成功响应
ApiResponseBuilder::success(data)
// 错误响应
ApiResponseBuilder::error("错误信息")// ✅ 正确:使用统一API客户端
import { apiGet, apiPost, apiPut, apiDelete } from './client'
// GET请求
const response = await apiGet<UserList>('users', { page: 1, pageSize: 20 })
// POST请求
const response = await apiPost<User>('users', userData)// web/service/users.ts
export const userApi = {
getUsers: (params?: { page?: number; pageSize?: number }) =>
apiGet<User[]>('users', params),
createUser: (data: CreateUserRequest) =>
apiPost<User>('users', data),
}
// nanostore 状态管理
import { atom, task } from 'nanostores'
export const $users = atom<User[]>([])
export const loadUsers = task(async (params?: { page?: number; pageSize?: number }) => {
const response = await userApi.getUsers(params)
$users.set(response.result || [])
})详细的API开发规范请参考:AGENTS.md
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Lit 3 UI │ │ REST API │ │ MQTT Client │
│ (web/) │ │ (apps/cloud/) │ │ (rumqttc) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
┌─────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Data Server │ │Message Server│ │ Scheduler │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────┐
│ Domain Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Device │ │ Alarm │ │ Event │ │
│ │ Domain │ │ Domain │ │ Domain │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────┐
│ Infrastructure Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Config │ │ Hardware │ │ Persistence │ │
│ │ System │ │ Abstraction │ │ (SQLite) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘
apps/cloud/
├── src/
│ ├── main.rs # 薄入口(<200 行):读配置 → 建 AppState → 组装 router → serve
│ ├── bootstrap.rs # 启动逻辑(日志、驱动重载、设备缓存预热)
│ ├── api/ # 路由挂载 + HTTP 中间件(WorkspaceScope, auth)
│ ├── modules/marketplace/ # 市场客户端(仅 HTTP DTO 契约,无编译期依赖)
│ ├── shared/ # 组合层胶水(app_state, config, service_manager)
│ ├── tests/ # 集成测试
│ ├── lib.rs # 库入口
│ └── server.rs # Axum 服务器启动
├── templates/ # 技能模板
├── Cargo.toml # Rust 项目配置
└── README.md # 后端说明
业务行为代码位于 apps/cloud/src/domains/<domain>/(thing, auth, user, tenant, event,
alarm, driver, notify, agent, mcp, admin),每域含 handler/service/dto;路由在
apps/cloud/src/api/mod.rs 集中挂载;全部 SQL 与迁移位于 crates/db/。
web/
├── src/
│ ├── ui/ # Lit Web Components
│ │ ├── components/ # 通用组件
│ │ ├── views/ # 页面视图
│ │ ├── controllers/ # 状态控制器
│ │ └── chat/ # AI 聊天 / A2UI 组件
│ ├── api/ # API 客户端
│ ├── i18n/ # 国际化
│ ├── styles/ # CSS 样式
│ ├── stores/ # nanostore 状态管理
│ └── types/ # TypeScript 类型定义
├── package.json
└── vite.config.ts
设计系统与样式规范见 web/DESIGN_SYSTEM.md,前端分层规范见 FRONTEND_LAYERING_GUIDE.md。
POST /api/v1/auth/login- 用户登录POST /api/v1/auth/logout- 用户登出GET /api/v1/auth/session- 获取会话信息
GET /api/v1/things- 获取物列表POST /api/v1/things- 创建物GET /api/v1/things/{id}- 获取物详情PUT /api/v1/things/{id}- 更新物DELETE /api/v1/things/{id}- 删除物GET /api/v1/things/{id}/profile- 获取物画像(属性/事件/操作 + LLM 本体摘要)GET /api/v1/things/{id}/ontology- 获取物本体定义GET /api/v1/things/{id}/tree- 获取物层级树POST /api/v1/things/{id}/actions/{name}/invoke- 调用物操作(需确认)POST /api/v1/things/{id}/actions/{name}/confirm- 确认并执行物操作POST /api/v1/things/import/dtdl/POST /api/v1/things/import/wot- DTDL / WoT 模型导入GET /api/v1/things/templates/{id}/export/dtdl- DTDL 模型导出GET /api/v1/things/resources/unassigned- 获取未关联的知识资源POST /api/v1/things/{id}/resources- 关联知识资源到物DELETE /api/v1/things/{id}/resources/{rid}- 解除物的资源关联
破坏性变更(v0.4.5.0):
/api/v1/devices管理端点已移除,请迁移至/api/v1/things。设备连接运行时接口(dashboard、命令执行、trace)仍保留在/api/v1/devices下。
GET /api/v1/drivers- 获取驱动列表GET /api/v1/drivers/{name}- 获取驱动详情GET /api/v1/drivers/{name}/config- 获取驱动配置参数GET /api/v1/drivers/names- 获取支持的驱动名称
GET /api/v1/device-templates- 获取模板列表GET /api/v1/device-templates/{id}- 获取模板详情GET /api/v1/device-templates/categories- 获取模板分类POST /api/v1/device-templates/{id}/validate- 验证模板输入POST /api/v1/device-templates/{id}/preview- 预览设备创建
GET /api/v1/alarms- 获取告警列表GET /api/v1/alarms/{id}- 获取告警详情GET /api/v1/alarms/recent- 获取最新告警GET /api/v1/alarms/statistics- 告警统计
GET /api/v1/alarm-rules- 获取告警规则列表POST /api/v1/alarm-rules- 创建告警规则GET /api/v1/alarm-rules/{id}- 获取告警规则详情PUT /api/v1/alarm-rules/{id}- 更新告警规则DELETE /api/v1/alarm-rules/{id}- 删除告警规则POST /api/v1/alarm-rules/{id}/toggle- 启用/禁用规则
GET /api/v1/workspaces- 获取工作空间列表POST /api/v1/workspaces- 创建工作空间GET /api/v1/workspaces/{id}- 获取工作空间详情PUT /api/v1/workspaces/{id}- 更新工作空间DELETE /api/v1/workspaces/{id}- 删除工作空间POST /api/v1/workspaces/{id}/devices- 分配设备到工作空间
GET /api/v1/jobs- 获取定时任务列表POST /api/v1/jobs- 创建定时任务GET /api/v1/jobs/{id}- 获取任务详情PUT /api/v1/jobs/{id}- 更新任务DELETE /api/v1/jobs/{id}- 删除任务POST /api/v1/jobs/{id}/toggle- 启用/禁用任务GET /api/v1/jobs/{id}/runs- 获取任务执行记录
GET /api/v1/self-healing/probes- 获取探针列表POST /api/v1/self-healing/probes- 创建探针GET /api/v1/self-healing/status- 获取自愈状态
GET /api/v1/events- 获取事件列表GET /api/v1/events/sse- SSE 事件流订阅GET /api/v1/events/real-time- 实时事件查询
GET /api/v1/notifications- 获取通知列表POST /api/v1/notifications/{id}/read- 标记已读GET /api/v1/notification-channels- 获取通知渠道POST /api/v1/notification-channels- 创建通知渠道
GET /api/v1/users- 获取用户列表POST /api/v1/users- 创建用户GET /api/v1/users/roles- 获取角色列表GET /api/v1/tenants- 获取租户列表
GET /api/v1/system/health- 健康检查GET /api/v1/system/features- 获取系统特性GET /api/v1/system/config- 获取系统配置GET /api/v1/system/initialization- 系统初始化状态
GET /api/v1/monitoring/health- 健康检查GET /api/v1/monitoring/metrics- 系统指标GET /api/v1/monitoring/dashboard/stats- 仪表板统计
GET /api/v1/agents- 获取 Agent 列表GET /api/v1/agents/{id}/config- 获取 Agent 配置PUT /api/v1/agents/{id}/config- 更新 Agent 配置GET /api/v1/agents/{id}/heartbeat/config- 获取心跳配置PUT /api/v1/agents/{id}/heartbeat/config- 更新心跳配置GET /api/v1/agents/{id}/heartbeat/logs- 获取心跳执行日志GET /api/v1/agents/{id}/heartbeat/tasks- 获取心跳任务列表PUT /api/v1/agents/{id}/heartbeat/tasks- 更新心跳任务GET /api/v1/agents/{id}/files- 列出工作空间文件GET /api/v1/agents/{id}/files/{name}- 读取工作空间文件PUT /api/v1/agents/{id}/files/{name}- 写入工作空间文件POST /api/v1/agents/skills- 创建/更新技能GET /api/v1/agents/skills- 获取技能列表GET /api/v1/agents/skills/{name}- 获取技能内容DELETE /api/v1/agents/skills/{name}- 删除技能POST /api/v1/chat/stream- SSE 流式聊天GET /api/v1/chat/history- 获取聊天历史
POST /mcp- MCP JSON-RPC 统一端点(tools/list、tools/call)POST /mcp/tools/list- 列出可用工具POST /mcp/tools/call- 调用指定工具POST /mcp/sse- MCP SSE 流式端点
贡献流程、分支策略与提交规范见 CONTRIBUTING.md。
- 在相应的API模块中创建处理函数
- 使用统一的响应构建器
- 遵循命名规范
// 示例:添加新API
use tinyiothub_web::response::ApiResponseBuilder;
async fn list_items(
Query(params): Query<ItemQuery>,
State(state): State<AppState>,
) -> Json<ApiResponse<Vec<Item>>> {
// 业务逻辑
let items = get_items(¶ms).await?;
ApiResponseBuilder::success(items)
}- 在
crates/runtime/src/driver/drivers/创建驱动文件 - 实现
DeviceDrivertrait - 在
mod.rs中注册驱动
// 示例:创建新驱动
use tinyiothub_core::driver::{DeviceDriver, DriverResult};
pub struct MyCustomDriver {
// 驱动配置
}
#[async_trait::async_trait]
impl DeviceDriver for MyCustomDriver {
async fn connect(&mut self) -> DriverResult<()> {
// 连接逻辑
}
async fn read_data(&mut self) -> DriverResult<Vec<u8>> {
// 数据读取逻辑
}
}- 在
web/src/api/目录创建 API 封装 - 使用统一的 API 客户端
// web/src/api/items.ts
import { apiGet, apiPost } from './client'
export interface Item {
id: string
name: string
createdAt: string
}
export const itemApi = {
getItems: (params?: { page?: number }) =>
apiGet<Item[]>('items', params),
createItem: (data: CreateItemRequest) =>
apiPost<Item>('items', data),
}- 在
web/src/ui/views/或web/src/ui/components/创建组件 - 使用
api/层提供的 API 客户端 - 遵循组件命名规范
// web/src/ui/views/item-list.ts
import { LitElement, html, css } from 'lit'
import { customElement, state } from 'lit/decorators.js'
import { itemApi } from '../../api/items'
@customElement('item-list')
export class ItemList extends LitElement {
@state() private items: Item[] = []
async firstUpdated() {
const response = await itemApi.getItems()
this.items = response.result || []
}
render() {
return html`
<div>
${this.items.map(item => html`<div>${item.name}</div>`)}
</div>
`
}
}# 后端(仓库根目录对整个 workspace 生效)
cargo fmt # 格式化代码
cargo check # 检查代码
cargo clippy # 代码检查
# 前端
cd web
pnpm dev # 开发服务器
pnpm build # 生产构建
pnpm test # 运行测试
pnpm preview # 预览生产构建cargo test # 运行后端测试
just ci # 完整 CI 检查(fmt + clippy + test)HarmonyOS 支持处于实验阶段,部署脚本:scripts/deploy-to-ohos.ps1(Windows)。
gateway/{sn}/heartbeat # 心跳消息
gateway/{sn}/device_regist # 设备注册
gateway/{sn}/command # 命令下发
gateway/{sn}/device_command # 设备命令
gateway/{sn}/data # 数据上传
gateway/{sn}/alarm # 告警消息
thing/{thing_id}/event/{event_name} # 物事件上报(节流 60/分钟,error/critical 不节流)
物事件上报的完整协议契约见 docs/device-event-contract.md。
- 物本体(Thing Ontology): 设备泛化为「物」— 层级树、物模板蓝图、属性/事件/操作、LLM 本体摘要,全新
/api/thingsAPI(v0.4.5.0) - 沉浸式工作空间: 3D 数字孪生场景 + AI 数据洞察面板,可折叠执行过程,玻璃拟态 UI
- A2UI 协议: 27 种动态 UI 组件(设备卡片、数据图表、Scene3D 等),AI 实时渲染仪表盘
- 工作空间资源管理: 场景模型、设备模型、图片、文档的上传与管理,语义搜索
- Cron 定时任务: 统一调度服务,Workspace 隔离,执行记录与统计
MIT License - 详见 LICENSE 文件