# scene-intelligent-agriculture **Repository Path**: edgeros/scene-intelligent-agriculture ## Basic Information - **Project Name**: scene-intelligent-agriculture - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 2 - **Created**: 2022-01-12 - **Last Updated**: 2026-03-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 智慧农业场景教程 本文是爱智场景搭建入门教程,需要配合https://gitee.com/edgeros/scene-intelligent-agriculture 仓库中的“scene-intelligent-agriculture”使用,其目的是为了让新人能够在零基础的情况下,跟着本教程完成并且理解如何搭建一个完整的爱智demo场景。 ## 一、整体介绍 本文介绍的是以搭载了 EdgerOS 的智能边缘计算机 Spirit 1 为核心,搭建一套可以应用智慧农业的智能浇水系统,可以持续检测土壤湿度并上报到 Spirit 1,根据应用中设定的适宜湿度区间,如果土壤干燥则通知浇水器进行浇灌,达到适宜湿度就停止,整体逻辑框图如下: ![在这里插入图片描述](image/智慧浇水逻辑框图.png#pic_center) ## 二、设备介绍及接线 ### 1、开发板选择 这里我们选择了安信可的 **ESP-32S** 开发板,这款开发板价格低廉,资料完善,性能也足以满足爱智场景开发的需求。 ![](image/ESP32.png) ### 2、土壤湿度传感器 这里选择了DFrboot 的 [土壤湿度传感器](https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-23951518078.13.384437fbB5wZdq&id=526393263881) ,在淘宝可以买到。 代码中传感器接线,通过一个: 使用 A0 控制(SVP/IO36),电源接3.3-5V都可以。 A0 -> A0 (SVP/IO36) VCC -> 3.3 - 5V GND -> GND ![土壤湿度传感器](image/土壤湿度传感器.png) ### 3、智能浇水器 智能浇水器稍微复杂一些,因为我是使用了现有的普通浇水器改造而成,通过继电器短路并且模拟按键型号完成操作。市面上类似产品很多这里就不具体要求,介绍一下整体思路。 控制电路: ![控制电路](image/继电器.png) 浇水器面板中间的按钮就是手动控制按钮下降沿触发,而我们在这里使用了一个继电器常开端接到按钮上,当开发板 12号 IO 口给继电器电压时,继电器常开端闭合,按钮被短接,两端电压被拉至5V,0.1S后断开,电压拉低,下降沿触发。 休眠监控电路: ![休眠控制电路](image/休眠控制电路.png) 浇水器中有一个10S左右没有控制就进入休眠状态的设置我们没办法修改,进入休眠状态后需要一个额外的触发来唤醒浇水器,而浇水器唤醒时,会点亮数码管,于是就通过 A0 引脚接到数码管的共阳级,如果检测到数码管的共阳级为低电平,就认为浇水器进入休眠状态,在触发命令之前额外触发一次,解除浇水器的休眠状态。 浇水器工作状态检测电路: ![电机监控电路](image/电机监控电路.png) 浇水器面板通过信号线来控制下面水泵电机的工作,这里是通过5号 IO 监控信号线的电压来确定电机的工作状态。 ## 三、整体效果展示 ![在这里插入图片描述](image/效果展示.gif#pic_center) ## 四、仓库结构介绍 ![](image/总目录.png) 仓库的核心是这两个文件夹,这也是一个爱智场景的完整组成结构:爱智应用与爱智设备 其中 `app` 文件夹是爱智应用代码,这是爱智场景的大脑,负担了整个爱智场景绝大部分的计算与调控。 而 `device` 文件夹是爱智设备代码,这是爱智场景的四肢,负担了整个爱智场景绝大部分的执行与采集。 ## 五、爱智前后端交互 对于 APP 侧获取设备的状态以及控制都是由 EdgerOS 中特有的 [Device](https://www.edgeros.com/edgeros/api/device.html) 模块提供的,APP 通过调用 Device 中的接口就可以实现获取设备列表监听设备消息以及向设备发送消息等。 设备侧通过 SDDC 协议只需要配置基本的设备信息就可以轻松的使设备连接到 Spirit 1 当中,相互消息传递使用的 JSON 也是轻量级的数据交互格式,简洁清晰,省去了构建特定报文格式的麻烦工作。 ![](image/前后端交互.png) ## 六、爱智 APP 开发流程 ### 1、开发工具配置 #### 安装 Visual Studio Code 下载并安装 [Visual Studio Code (opens new window)](https://code.visualstudio.com/download)。 #### 安装 EdgerOS 扩展插件 该插件可供开发者在爱智设备上**打包**,**上传**,**安装**和**更新**爱智应用,并向开发者提供**爱智应用开发模板**。 [下载 EdgerOS 扩展插件](vscode:extension/edgeros.edgeros) ,插件 ID 为 edgeros.edgeros,然后点击**安装**按钮,完成 EdgerOS 扩展插件的安装。 #### 安装 EdgerOS 安全证书 为保护用户信息安全,请[安装 EdgerOS 安全证书](https://www.edgeros.com/edgeros/guide/start/install_ca.html) 。 ### 2、创建 APP #### 新建项目 使用 EdgerOS for Visual Studio Code 扩展插件**新建项目**: 1. 打开 Visual Studio Code,单击插件 **EdgerOS** > **创建项目**。 2. 根据所开发项目的需求选择**模板**,然后点击**立即应用**。 > 注意:如果模板加载不出来请按照以下方式切换模板源:打开 VSCode 左下方的管理按钮,点击**设置>用户>扩展> EdgerOS > Template Source** 将模板源切换为 **Gitee**,然后在创建模板时点击**刷新模板信息**按钮。 ![ide](image/新建项目.gif) 3. 参考表 1 填写模板参数,填写完后点击**立即创建**,此时一个爱智应用已创建完成。 4. 最后,进入创建的项目的根目录,执行 `npm install` 安装项目依赖包。 ![ide](image/新建项目2.gif) 表 1 项目模板参数 | 参数 | 说明 | 取值样例 | | ------------------------ | ------------------------------------ | -------------------------------- | | 项目名称 | 该项目的工程文件名称 | test | | 包名 | 软件包名称 | com.example.myapp | | 项目描述 | 简要说明项目用途 | 测试项目 | | 保存路径 | 项目在本地保存路径 | N/A | | 版本号 | 应用的版本号 | 0.0.1 | | 提供商 ID | 开发者 ID (从开发者网站个人信息查询) | 479ace68109611ecbf6b00163e163bca | | 提供商名称 | 开发者 ID 对应的用户名 | acoUsername | | 提供商邮箱 | 开发者的邮箱 | example@example.com | | 提供商手机 | 开发者的手机号 | 123456789 | | 其他项:在新窗口打开项目 | 是否在新的 VScode 窗口打开项目 | N/A | #### 文件结构介绍 创建项目后会在项目目录下生成一个文件夹(文件夹名称为项目名称),作为项目根目录。 这个文件夹中已经包含了项目配置文件与示例页面的初始代码,项目根目录主要结构如下: ```text ├── assets 资源文件夹 ├── routers 路由信息 ├── public 静态页面文件 ├── views 模板页面 ├── eslintrc.json eslint 配置文件 ├── edgeros.json edgeros 应用配置文件 ├── main.js 程序入口 ├── jsconfig.json 代码补全配置文件 └── package.json 依赖包的管理 ``` edgeros.json 文件详解见附录一 ### 3、APP 开发 整个 APP 开发分为前端 UI 开发,以及后端主体业务逻辑开发,以下为 APP 的目录结构: ![](image/APP目录.png) #### APP 前端 UI 开发 前端 UI 界面放了一个数据显示面板,一个设备选择模块,一个设备参数设置模块,具体开发实现就不展开细说了。 ![](image/应用演示.png) #### APP 后端代码开发 关于实现的代码主要就是利用了设备模块 [device](https://www.edgeros.com/edgeros/api/device.html),具体的业务相关代码见 `scene-intelligent-agriculture\app\eap\data\device.js` 文件, 主要的接口功能使用如下 : ```javascript const Device = require('device'); const deviceMap = new Map(); // 设备列表集合 // 获取设备列表 Device.list(true, (error, list) => { if (error) { console.error('Device.list error!' + error); } else { list.forEach((item) => { Device.info(item.devid, (error, info) => { if (error) { console.error('Device.info error!' + error); } else { deviceMap.set(item.devid, { devid: item.devid, ...info, }); } }); }); } }); // 监听设备加入 Device.on('join', function (devid, info) { deviceMap.set(devid, { devid, ...info }); io.emit('list', [...deviceMap.values()]); // 通过socket.io推送数据到前端 }); // 监听设备丢失 Device.on('lost', function (devid) { deviceMap.delete(devid); io.emit('list', [...deviceMap.values()]); // 通过socket.io推送数据到前端 }); ``` 发送消息和监听设备消息也比较简单: ```javascript ... const dev = new Device(); ... // 发送消息 dev.send({unit: 'Centigrade'}, (err) => { ... }, 3) // 监听接收设备发送的消息 device.on('message', function (msg) { ... console.log('message: ', msg) // 可以通过telnet 192.168.128.1 81端口进行查看日志打印 io.emit('message', msg); ... }); ``` ## 七、爱智设备开发流程 爱智设备的对硬件没有太多的要求,只要支持 Wi-Fi, ZigBee, LoRa其中一种协议的设备就行,其中比较推荐 SDDC 协议,因为爱智系统对 SDDC 的支持是比较完善的,网上的各种Wi-F-模块也有很多很全面的教程更加适合新手使用,本文也会以 SDDC 协议为例介绍爱智设备搭建的全过程。 ### 1、开发环境搭建 #### 安装IDE 软件开发第一步当然是安装 IDE ,这里推荐一个国内社区分享的:[国内 Arduino IDE下载](https://www.arduino.cn/thread-5838-1-1.html). 官方下载链接: [官方 Arduino IDE下载](https://www.arduino.cc/en/software).都是免费的,只不过官方下载可能慢。 下载之后也没有什么安装过程,解压就能用,打开之后会出现: ![Arduino IDE 1.8.15](image/arduino-IDE.png) 这是 Arduino - IDE 创建的一个工程,里面附带了Arduino 的基本结构和函数。与C语言不同,Arduino 没有 main 函数,取而代之的是 setup 与 loop 函数。 setup 函数是 Arduino 的硬件初始化函数,也是**整个代码第一个运行的函数(仅会运行一次)**,你需要在这里面进行一些初始化操作和设置,比如说设置引脚,设置串口波特率,初始化传感器什么的。当然一些不适合放入 loop 循环,又可以在loop 之前运行的函数也可以放 setup 函数中调用(比如说创建一些线程)。 而 loop 函数的作用就相当于一个死循环的 main 函数,loop 相当于: ``` main() { deviceinit(); // 硬件初始化 while(1) { // loop 函数里的代码相当于运行在这 } } ``` 但是需要注意的是,loop 与 main 不同的是,loop 不是整个程序的入口,不是第一个运行的函数,setup 才是! #### 导入硬件库 arduino 屏蔽掉了底层硬件代码,当然不是真的让这些代码消失了,而是封装成了一个个库,我们直接下载的 IDE 只带有官方的 AVR 开发板,ESP-32 开发板的库需要我们自己导入。 打开"文件"选项卡找到点击"首选项": ![](image/首选项.png) 点击后会出现一个对话框,在附加开发板管理器中添加 https://github.com/espressif/arduino-esp32/releases/download/1.0.5/package_esp32_index.json : ![](image/添加网址.png) 添加网址成功后,"工具"选项卡找到点击"开发板",里面有个"开发板管理器": ![](image/开发板管理器.png) 打开之后输入 ESP32 并且点击安装即可: ![](image/安装.png) 这样就完成了开发板开发环境的搭建工作。 ### 2、device 侧开发 进入`device`目录你会看见三个文件夹: ![](image/文件夹结构.png) cjson :标准的 cjson 库,放到 arduino 安装目录下的 libraries 文件夹里,因为 SDDC 协议报文传输的是 JSON 字符串,以保证数据的的跨平台性。 libsddc:是 SDDC 库和 用户“灵感桌面”开发并分享的 SDK ,也是放入 libraries 文件夹里就行。里面是 SDDC 协议的处理函数。 demo :就是具体的设备代码。 demo文件夹里面: ![](image/demo程序.png) SEN0193 是土壤湿度传感器代码,Watering 是浇水器代码。具体代码详解参考附录三: ### 3、烧录代码 `SEN0193_sddc_demo` 文件夹里面就是我们代码,点进去就能看见 `SEN0193_sddc_sdk_demo.ino` 文件,双击文件会自动启动 `arduino-IDE` 打开代码。在工具 -> 端口 选择对应的 COM 口然后点击上传就可以把代码烧录到板子里: ![](image/烧录代码.png) ### 4、设备连接到爱智 代码烧录完成之后设备会自动SDDC协议运行并与精灵一号进行通讯。 #### 添加设备 1. Wi-Fi 物联网设备连接到 精灵一号 的 Wi-Fi AP 后,会以 SDDC 协议连接 EdgerOS,EdgerOS 将发现新的设备: ![avatar](image/发现新设备.png) 2. 点击 “添加”,即可把设备加入到 EdgerOS(如果是加密设备,需要输入设备密码,如上面代码的 `1234567890`) #### SmartConfig 连接方式也支持 smartconfig 详见:附录二 ## 附录一:edgeros.json 详解 ```json { "name":"default", "bundleid": "com.example.myapp", "ignore_modules": [ "@edgeros/eslint-plugin-jsre", "@edgeros/jsre-types" ], "ignore_path": [ "./test/**", "./temp/**" ], "assets": { "ico_big": "assets/big.png", "ico_small": "assets/small.png", "ico_widget": "assets/widget.png", "splash": "assets/splash.png" }, "program": { "gss": false, "log": "console", "will": false, "reside": false, "mesv": "1.0.0", "experimental": false }, "loading":{ "splash":"splash", "background":"#000000", "animation":"enlarge" }, "vendor": { "id": "479ace68109611ecbf6b00163e163bca", "name": "mycompany", "email": "example@example.com", "phone": "123456789", "fax": "" }, "update": { "remove": [ "public" ] }, "widget": [ { "ico": "ico_widget", "name": "My Widget", "path": "widget", "rows": 2, "columns": 2, "category": "Demo" } ] } ``` #### 字段描述 | **字段** | **类型** | **描述** | **用途** | | -------------- | -------- | ----------- | ------------------------------------------------------------ | | name | 字符串 | App 名称 | 在爱智世界中展示时的应用名称 | | bundleid | 字符串 | App 的包名 | App 包名 (bundleid),建议使用反域名序列,例如 `com.example.myapp` | | ignore_modules | 字符串 | module 名称 | 过滤不参与打包的 module 名称 | **ignore_path** | **字段** | **类型** | **描述** | **用途** | | ----------- | -------- | ---------- | ------------------------ | | ignore_path | 字符串 | 字符串路径 | 过滤不参与打包的文件路径 | **assets** | 字段 | 类型 | 描述 | 用途 | 注意事项 | | ---------- | ------ | ------------------------------ | ------------------------------------------------- | ------------------------------------------------------------ | | ico_big | 字符串 | App 必须的高清图标的资源路径 | *暂未使用* | 必须存在于软件包的根目录下且为 PNG/JPG/JPEG 格式; 在深色模式和浅色模式下必须保持清晰; 图标尺寸为 160*160(px) 至 240*240(px); 文件大小不超过 100 KB。 | | ico_small | 字符串 | App 必须的小图标的资源路径 | 用于 App 桌面图标的圆角矩形图片 | 必须存在于软件包的根目录下且为 PNG/JPG/JPEG 格式; 在深色模式和浅色模式下必须保持清晰; 图标尺寸为 160*160(px) 至 180*180(px); 文件大小不超过 100 KB。 | | ico_widget | 字符串 | 可自定义名称的其它可引用的资源 | 此处 ico_widget 定义 widget 中 图标图片文件的路径 | / | | splash | 字符串 | 可自定义名称的其它可引用的资源 | 此处 splash 定义欢迎页图片文件的路径 | 格式为 PNG/JPG/JPEG/GIF; 文件大小不超过 2048 KB。 | **program** | **字段** | **类型** | **默认值** | **权限申请** | **描述** | **用途** | | ------------ | -------------- | ---------- | ------------ | ------------------------------------------------------------ | --------------------------------- | | gss | 选填,布尔值 | false | N/A | 相同开发商 (vendor.id) 发布的所有 App 可通过 gss 通信,不同开发商的 App 通过 zone 隔离;系统服务的 zone 为空;App 无法创建空的 zone | 用于控制同一开发商 App 间的通信 | | log | 选填,字符串 | console | N/A | "file":保存日志到文件;日志文件有两个,写满后自动滚动输出到另外一个;"null":不输出任何日志;"console":仅允许在开发调试阶段使用 | 用于控制日志的输出方式 | | will | 选填,布尔值 | false | 需要 | App 不会被立即杀死,以便完成自己的任务 | 用于控制 App 的遗嘱权限 | | reside | 选填,布尔值 | false | 需要 | 常驻内存权限,比如说提供 widget 的 App | 用于控制 App 的常驻内存权限 | | mesv | 必填,整数数组 | N/A | N/A | 整数数组 Minimal Edger system version,即最低兼容的 EdgerOS 版本 | 填写最低兼容的 EdgerOS 版本 | | experimental | 选填,布尔值 | false | N/A | 表示该应用是否是一个实验室应用 | 用于控制 App 是否为一个实验室应用 | **loading** | 字段 | 类型 | 描述 | 用途 | | ---------- | ------ | --------------------------------- | ------------------------------------------------------------ | | splash | 字符串 | `splash` 引用 assets 字段中的资源 | App 加载首屏的图片文件,引用 assets 字段内定义资源文件的字段名 | | background | 字符串 | `#000000` 格式的颜色编码值 | App 加载首屏的图片文件的背景色 | | animation | 字符串 | `enlarge` 动画效果:扩大 | App 加载完成后,首屏图片的退出动画效果 | **update** | **类型** | **字段** | **可选字段** | **描述** | **用途** | | -------- | -------- | ------------ | ------------ | ---------------------------------- | | 数组 | remove | N/A | 自动清理目录 | 应用升级时,系统自动清理的目录集合 | **widget** | **字段** | **类型** | **字段说明** | **描述** | **用途** | | -------- | -------- | ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | ico | 字符串 | 必填 | widget 图标,例如:`ico_widget` | widget 图标,引用 assets 字段内定义的资源文件 | | name | 字符串 | 必填 | widget 显示名称 | 用于记录 widget 图标名称 | | path | 字符串 | 必填 | widget page URL 路径,最终会与 App 的 hostname 拼接成完整URL | 用于记录 widget 的加载路径 | | rows | 数字 | 必填 | widget 占用行数 | 用于记录 widget 占用桌面栅格的行数 | | columns | 数字 | 必填 | widget 占用列数 | 用于记录 widget 占用桌面栅格的列数 | | category | 字符串 | 可选 | widget 所述分类, 多个 widget 可属于一个组,EdgerOS 会预定义一些 分类,没有指定分类则分类名以 name 代替 | 记录 widget 的分类,可以从 EdgerOS 的分类里选择,如果没有指定分类则分类名以 name 代替 | **vendor** | **字段** | **类型** | **字段说明** | **描述** | **用途** | | -------- | -------- | ------------ | ---------------------------- | ------------------------------------------------------------ | | id | 字符串 | 必填 | 系统为用户生成的 ID | 系统为用户生成的 ID,可以在爱智开发者平台的个人信息中查看,例如:479ace68109611ecbf6b00163e163bca | | name | 字符串 | 必填 | 软件开发商名称 | 用于记录 App 开发者的用户名或者开发厂商的名称 | | email | 字符串 | 必填 | 软件开发商的联系电子邮件地址 | 用于记录 App 开发商的电子邮件地址 | | phone | 字符串 | 可选 | 软件开发商的联系电话 | 用于记录 App 开发商的联系电话 | | fax | 字符串 | 可选 | 软件开发商的传真号码 | 用于记录 App 开发商的传真号码 | ## 附录二:smartconfig 1. 令 Wi-Fi 物联网设备进入 SmartConfig 模式,不同的 Wi-Fi 物联网设备进入 SmartConfig 模式的操作方式可能有所差异,我们 demo 代码中设置的是长按 IO0 按键进入 SmartConfig 模式。 2. 手机通过爱智 App 进入 EdgerOS 后,打开 “设备” App,进入 “设备管理” 界面: ![avatar](image/设备管理.png) 3. 在 “设备管理” 界面,点击下方的 “加号” 图标进入 “扫描设备” 界面: ![avatar](image/扫描设备.png) 4. 在 “扫描设备” 界面,点击 “高级设置”: ![avatar](image/高级设置.png) 5. 配置 Wi-Fi 物联网设备需要连接到的 精灵一号 的 Wi-Fi AP SSID 和密码(一般保持默认,即连接到当前手机连接到的 精灵一号),打开 “启用 SmartConfig” 开关,最后点击 “完成” 按钮: ![avatar](image/smart_config配置.png) 启用 SmartConfig 后, “扫描设备” 页面右下角会出现 “SmartConfig” 提示: ![avatar](image/打开smartconfig.png) 6. 等待 SmartConfig 完成(即 Wi-Fi 物联网设备连接到指定的 精灵一号 的 Wi-Fi AP),一般需要 15 秒左右 ## 附录三:设备代码讲解 为了方便讲解逻辑,我会打乱代码的顺序可能还会进行裁剪。 ### 1、土壤湿度传感器 #### 设备控制命令: 通过 Spirit 1 的应用程序或者[嗅探器](https://blog.csdn.net/lixiaocheng1983/article/details/119652855?spm=1001.2014.3001.5502) 向传感器设备发送的命令, 其中的命令数据采用的是 JSON 格式。 传感器本身会按周期主动上报当前土壤湿度,同时还可以通过 get 命令主动获取当前土壤湿度: ```c { "method": "get", // 这个命令可以主动获取当前土壤湿度 "obj": ["soil_humidity"] } ``` 如果默认的数据上报周期不符合需要还可以通过 set 命令来调整主动上报的间隔: ```c { "method": "set", // 这个命令可以调整传感器主动上报的时间间隔,土壤湿度变化应该不会很快,可以设置慢一些 "periodic_time": 1000 // periodic_time是关键字,需要和下文的函数注册字段一致 } ``` #### 设备和协议初始化流程: 这部分基于官方 demo 写的不需要做什么修改,主要是设备初始化,管脚配置,和协议初始化部分。 传感器初始化部分,因为这个传感器输出只是普通的电压值,用一般的 IO 口即可读取,不需要初始化额外的串口或者 I2C,但是主动上报流程中需要加延时,为了不阻塞其他任务需要单独创建一个线程 。 设备和协议初始化部分,代码基本不需要改动,并且过长,这里就不放出来。(代码中注释内容的实现代码可参考对应文件 `scene-intelligent-agriculture\device\demo\SEN0193_sddc_demo\SEN0193_sddc_demo.ino`) ```c /* * 初始化传感器 */ void sensor_init() { // 创建传感器任务,周期性获取土壤湿度传感器的数据并发送给 EdgerOS xTaskCreate(periodic_sensor_task, "periodic_sensor_task", ESP_TASK_STACK_SIZE, NULL, ESP_TASK_PRIO, NULL); } void setup() { // 初始化显示串口 // 初始化传感器 sensor_init(); // 清除一下按键状态机的状态 // 创建按键扫描线程,长按 IO0 按键,松开后 ESP32 将会进入 SmartConfig 模式 // 启动 WiFi 并且连接网络 // 获取并打印 IP 地址 // sddc协议初始化 // 获取并打印网卡 mac 地址 // 使用网卡 mac 地址设置设备唯一标识 UID } void loop() { // 运行 SDDC 协议循环 // 销毁 SDDC 协议 } ``` #### 配置设备信息 这部分代码可以配置 WiFi 名称和 WiFi 密码,要使用的引脚,并且配置设备在 Spirit 1 上显示的信息: ```c #include "Arduino.h" #include #include #include #include #include #define SDDC_CFG_PORT 680U // SDDC 协议使用的端口号 #define PIN_INPUT 0 // 选择 IO0 进行控制 #define ESP_TASK_STACK_SIZE 4096 #define ESP_TASK_PRIO 25 static const int sensor_in = A0; // 数据输入引脚 static const char* ssid = "EOS-000041"; // WiFi 名 static const char* password = "1234567890"; // WiFi 密码 const float AirValue = 3000; //初始化最大干燥 (传感器在空中的情况。这个需要根据你自己传感器情况初始化) const float WaterValue = 1400; //初始化最大湿度 (传感器放入水中的情况。这个需要根据你自己传感器情况初始化) int intervals = (AirValue - WaterValue) / 3; static int xTicksToDelay = 10000; // 周期延时时间 OneButton button(PIN_INPUT, true); ``` 这里填写设备的信息,方便在 Spirit 1 上查看和寻找你需要的设备: ```c /* * 当前设备的信息定义 */ DEV_INFO dev_info = { .name = "土壤湿度传感器", .type = "device", .excl = SDDC_FALSE, .desc = "ESP-32S", .model = "1", .vendor = "inspiration-desktop", }; ``` #### 回调函数注册 这是收到命令后回调函数注册的位置,在这里注册的函数才能被 SDK 正确的调用,执行正确的动作。 土壤湿度传感器输出 (get命令) 的土壤湿度是数字量,所以在 *系统对象状态获取注册* 中注册处理函数时,第二个参数需要设定为 *DEV_NUM_TYPE*,而 对应的处理函数是single_get_sensor。 ```c /* * 系统对象状态获取注册 */ DEV_STATE_GET dev_state_get_reg[] = { {"soil_humidity", DEV_NUM_TYPE, single_get_sensor}, // 输出数字量,所以第二个参数为 DEV_NUM_TYPE }; ``` 输入(set 命令)的上报时间间隔也是数字量,所以在 *数字量设备对象函数与处理方法注册* 中注册 "periodic_time" 命令处理函数。 ```c /* * 数字量设备对象函数与处理方法注册 */ NUM_DEV_REGINFO num_dev[] = { {"periodic_time",periodic_time_set}, }; ``` 因为没有其他输入,所以 *显示设备对象函数与处理方法注册* 和 *IO设备对象设置函数与处理方法注册* 为空。 ```c /* * 显示设备对象函数与处理方法注册 */ DIS_DEV_REGINFO dis_dev[] = { }; /* * IO设备对象设置函数与处理方法注册 */ IO_DEV_REGINFO io_dev[] = { }; ``` 具体 SDK 的解析可以参考用户“灵感桌面”的 [同人逼死官方系列!基于sddc 协议的SDK框架 sddc_sdk_lib 解析](https://blog.csdn.net/lixiaocheng1983/article/details/120060539) 和 [同人逼死官方系列!从 DDC 嗅探器到 sddc_sdk_lib 的数据解析](https://blog.csdn.net/lixiaocheng1983/article/details/120350575) #### 数据获取与发送流程 这里是根据业务自行编写的处理流程 ,可以根据需求自行更改。 以下代码为根据设置的上报周期定时上报土壤湿度数据: ```c /* * 周期上报函数 */ static void periodic_sensor_task(void *arg) { while(1) { // 任务创建之后,设定延时周期 delay(xTicksToDelay); // 调用主动数据上报函数 get_sensor(); delay(100); } // 已停止发送数据 Serial.printf("Soil humidity data OFF\n"); } ``` 以下为主动上报数据函数,其中构建了一个 json 报文通过 object_report 接口上报: ```c /* * 主动数据上报函数 */ static void report_sensor_state() { int sensorValue = 0; cJSON *value; cJSON *root; char *msg; value = cJSON_CreateArray(); root = cJSON_CreateObject(); sddc_return_if_fail(value); sddc_return_if_fail(root); sddc_return_if_fail(value); // 组装上报报文 cJSON_AddItemToArray(value, cJSON_CreateString("soil_humidity")); cJSON_AddItemToObject(root, "obj", value); // 将组装好的报文传给上报函数 msg = cJSON_Print(root); sddc_printf("主动上报: %s\n",msg); object_report(root); cJSON_Delete(value); cJSON_free(msg); } ``` 以下代码为注册的设置上报周期的回调函数: ```c /* * 设置周期等待时间 * 这是在上文注册的 set 命令处理函数 */ sddc_bool_t periodic_time_set(const uint64_t value) { sddc_printf("修改主动上报周期!\n"); xTicksToDelay = value; return SDDC_TRUE; } ``` 以下代码为注册的 get 土壤湿度数据接口: ```c /* * 单次获取数据 * 这是在上文注册的 get 命令处理函数 */ sddc_bool_t single_get_sensor(char *objvalue, int value_len) { // 计算湿度百分百 float value = 100 - (((analogRead(sensor_in))-WaterValue)/(AirValue - WaterValue))*100; if(value > 100) { value = 100; } snprintf(objvalue, value_len, "%f", value); return SDDC_TRUE; } ``` ### 2、智能浇水器 #### 设备控制命令: 通过 Spirit 1 的应用程序或者 [嗅探器](https://blog.csdn.net/lixiaocheng1983/article/details/119652855?spm=1001.2014.3001.5502) 向传感器设备发送的命令: 通过向浇水器发送 "ON"/"OFF" 的 set 命令可以控制浇水器是否浇水: ```c { "method": "set", // 控制浇水器开始/停止浇水 "watering": "ON"/"OFF" } ``` 通过向浇水器发送 "watering" 的 get 命令可以获取浇水器是否有在浇水: ```c { "method": "get", // 获取浇水器工作状态 "obj": ["watering"] } ``` #### 设备和协议初始化流程: 参考上面土壤湿度传感器介绍。 #### 配置设备信息 参考上面土壤湿度传感器介绍。 #### 回调函数注册 参考上面土壤湿度传感器介绍。 #### 数据获取与发送流程 参考上面土壤湿度传感器介绍。