尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
IoT-For-Beginners 智慧农业实战:用 6 堂课从土壤传感器到云端物联网农场
IoT-For-Beginners 智慧农业实战用 6 堂课从土壤传感器到云端物联网农场【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners数字农业正在重塑农业生产的每一个环节——从预测作物生长、感知土壤墒情到自动灌溉、上云迁移与设备安全。本篇文章基于开源课程项目 IoT-For-Beginners 的第二个学习项目Zemеделие с IoTFarming with IoT系列见 translations/bg/2-farm/README.md英文原版见 2-farm/README.md完整梳理其 6 节课的知识脉络与可运行代码帮助你掌握一套从零搭建传感器 → MQTT/云 → 执行器闭环智慧灌溉系统的完整技术方案。为什么农业需要物联网随着全球人口持续增长农业承受的压力与日俱增。可供耕作的土地总量几乎不变而气候变化却在不断加剧挑战——尤其是对于依赖种植成果养家糊口的约 20 亿自给自足型农民subsistence farmers而言。物联网恰恰能帮助农民做出更聪明的决策种什么、何时收从而提升产量、减少人工、及时发现并处理虫害。在这个项目中你将学会如何把物联网应用到农业场景中最终实现数字化农业Digital Agriculture的核心能力温度测量——通过温度预测植物生长与成熟周期自动化灌溉——测量土壤湿度仅在土壤缺水时启动灌溉系统取代定时浇水定时浇水在炎热干旱期会浇水不足在雨季又会过度浇水虫害防治——利用自动化机器人或无人机上的摄像头巡检虫害只在需要处喷洒农药减少农药用量及其对水源的污染。课程总览6 节课的递进路线本系列共 6 节课从单点传感器测量一路演进到云端安全部署形成一条完整的工程主线序号主题核心能力1用物联网预测植物生长测量环境温度、计算生长度日GDD、MQTT 发布遥测、服务端落盘2检测土壤湿度湿度传感器原理、传感器与 IoT 设备通信协议、传感器标定3自动化植物浇水继电器控制大功率水泵、MQTT 下发命令、传感器/执行器时序控制4将植物迁移到云端云与 IoT Hub 概念、Azure CLI 建资源组与 IoT Hub、设备注册与直连5将应用逻辑迁移到云端Serverless、Azure Functions、IoT Hub 事件触发器、Registry Manager 下发直连方法6保障植物安全加密原理、对称密钥与连接字符串、X.509 证书认证课程中会使用部分云资源若未完整完成本项目的所有课时建议参考 clean-up.md 清理云资源避免产生不必要的费用。第 1 课用物联网预测植物生长温度为什么对种植至关重要植物生长需要水、二氧化碳、养分、光照与热量。大多数人对前几项很熟悉却常常忽略热量——这正是植物在春季气温回升时开花、温室能促进植物生长、暖冬时雪莲花或水仙提前发芽的原因。针对日均温度每种植物都存在三个关键温度基础温度Base temperature植物能够生长的最低日均温度最适温度Optimum temperature植物生长最快的日均温度最高温度Maximum temperature植物能承受的温度上限超过后植物会停止生长以保水存活。 以上均为昼夜平均温度。植物昼夜需要不同温度白天更高效地进行光合作用、夜间节省能量。不同植物物种这三个温度值各不相同这就是为什么有些植物适合热带、有些适合寒带。下图展示了生长速率—温度关系曲线低于基础温度无生长速率随温度升高至最适温度达峰之后回落至最高温度时生长停止如果农民能控制温度例如商业温室就可以为植物优化环境——比如商业番茄温室白天约 25°C、夜间约 20°C以获得最快生长。生长度日Growing Degree DaysGDD生长度日又称生长度单位是以温度衡量植物生长的指标在水分、养分、CO₂ 充足的前提下温度决定生长速率。GDD 按天计算即一天的平均温度°C减去植物基础温度。每种植物成熟、开花、结果都需要一定数量的 GDD每天累积的 GDD 越多植物长得越快。GDD 的完整公式较复杂课程使用一个常用的简化近似公式GDD生长度日数量T_max当日最高温度°CT_min当日最低温度°CT_base植物基础温度°C玉米示例不同品种的玉米成熟需要 8002,700 个 GDD基础温度 10°C。若某日测得最高温 16°C、最低温 12°C则当日 GDD (16 12) / 2 − 10 4。若该品种玉米需 800 GDD 成熟则还需累积 796 个 GDD 还有处理 T_max 高于 30°C 或 T_min 低于 T_base 的变体公式本课先忽略这些边界情况。从传感器数据计算 GDD 的完整架构植物不会按固定日期生长例如你无法确定种子播下后 100 天必然结果。农民只能凭经验粗略判断成熟时间再每日巡检——这对大型农场是巨大的人力负担还容易漏掉意外早熟的作物。通过测量温度计算 GDD农民只需在接近预期成熟期时检查。物联网方案的标准架构是IoT 设备测量温度 → 通过 MQTT 等协议将遥测数据发布到互联网 → 服务端代码订阅数据并存储如数据库或 CSV→ 后续分析如夜间任务计算当日 GDD、累计各作物 GDD并在接近成熟时告警服务端还可以为数据补充额外信息IoT 设备发布自身标识服务端据此查表得到设备位置与监测的作物类型还可以补充当前时间——因为部分 IoT 设备缺少精确时钟硬件或需要额外代码通过网络读取时间。实战发布温度遥测并落盘为 CSV课程提供了三套硬件路径的引导文档Wio Terminal / Raspberry Pi / 虚拟设备温度发布与 MQTT 连接说明见 2-farm/lessons/1-predict-plant-growth。服务端完整实现见 code-server/temperature-sensor-server/app.py其核心逻辑client_name id temperature_sensor_server # 客户端标识反映项目名 temperature_file_name temperature.csv # CSV 文件名 fieldnames [date, temperature] # 两列日期与温度 if not path.exists(temperature_file_name): with open(temperature_file_name, modew) as csv_file: writer csv.DictWriter(csv_file, fieldnamesfieldnames) writer.writeheader() # 首行写入列头 def handle_telemetry(client, userdata, message): payload json.loads(message.payload.decode()) print(Message received:, payload) with open(temperature_file_name, modea) as temperature_file: temperature_writer csv.DictWriter(temperature_file, fieldnamesfieldnames) temperature_writer.writerow({date: datetime.now().astimezone() .replace(microsecond0).isoformat(), temperature: payload[temperature]})关键要点client_name使用id temperature_sensor_server形式保证 MQTT 客户端标识唯一CSV 采用追加模式modea写入日期列使用ISO 8601 格式含时区、不含微秒温度列来自遥测消息运行一段时间后的temperature.csv形如date,temperature 2021-04-19T17:21:36-07:00,25 2021-04-19T17:31:36-07:00,24理想情况下应连续采集一整天数据再做 GDD 计算若用虚拟设备可勾选 random 并设置范围避免每次返回相同温度值。实战手工计算 GDD例如草莓基础温度为 10°C。某日temperature.csv中最高温 25°C、最低温 12°C则(25 12) / 2 − 10 8.5当日草莓获得8.5 个 GDD。草莓结果约需 250 个 GDD因此还需继续累积课程的课后作业要求使用仓库提供的 gdd.ipynb Jupyter Notebook 可视化温度数据并计算 GDD安装pandas、matplotlib、jupyter后执行jupyter notebook gdd.ipynb评分标准是至少捕获 12 天的完整数据。第 2 课检测土壤湿度土壤湿度的意义与测量方式植物吸收水分用于三件事光合作用水CO₂光生成碳水化合物与氧气、蒸腾作用通过叶片气孔交换 CO₂同时输送养分、类似出汗般为植物降温、以及维持结构植物约 90% 是水比人类的 60% 还高水让细胞保持刚性缺水会萎蔫甚至死亡。土壤过干植物无法吸收足够水分过湿则根部无法获得足够氧气导致根系死亡。因此理想的土壤应不干不涝物联网通过测量土壤湿度让农民按需浇水。常用的传感器有两种电阻式Resistive两根探针插入土壤一端通电、另一端接收通过测量土壤电阻判断湿度。水是良好导体土壤含水越高电阻越低电容式Capacitive测量正负电极板间可存储电荷量电容。土壤电容随湿度变化并转换为电压土壤越湿输出电压越低。两者都是模拟传感器通过电压表示湿度——那么电压如何变成代码里的数值这引出了传感器与 IoT 设备的通信机制。传感器如何与 IoT 设备通信GPIO 引脚GPIO 是一组可连接硬件的引脚Raspberry Pi、Wio Terminal 等开发板常见部分引脚提供 3.3V/5V 电压部分为接地其余可通过程序设为输出发送电压或输入接收电压。仅需开关量高/低的数字传感器与执行器可直接使用 GPIO例如按钮连接在 5V 与输入引脚之间按下时回路接通、读到高电平LED 连接在输出引脚与地之间需串联电阻防止烧毁输出高电平即点亮。模拟引脚与 ADCArduino 等设备提供带 ADC模数转换器的模拟引脚将电压范围转换为数值。通常 ADC 为 10 位分辨率即把电压映射为 01,023 的整数。例如 3.3V 板子上传感器返回 3.3V 则读到 1,023返回 1.65V 则读到 511。土壤湿度传感器依赖电压因此走模拟引脚返回 01,023。回顾第一项目小夜灯课程光传感器返回 01,023——Wio Terminal 直接接模拟引脚Raspberry Pi 则经 Grove Base Hat 上集成 ADC 的模拟引脚通信虚拟设备模拟模拟引脚发送 01,023 的值。通信协议I²C、UART、SPI 与无线I²C多控制器多外设协议数据以带地址的数据包传输设备地址通常出厂硬编码。总线由 SDA串行数据、SCL串行时钟两根主线和 VCC、GND 两根电源线组成。数据发送时某设备发出起始条件成为控制器发送目标设备地址及读/写标志传输完成后发停止条件。I²C 有三种速度模式标准模式 100Kbps、快速模式Raspberry Pi 上限 400Kbps、高速模式 3.4MbpsUART两设备间点对点串行通信各有一个发送Tx与接收Rx引脚交叉相连实现双向传输。通过波特率常用 9,600bps确定传输速度用起始位与停止位界定一个字节8 位数据SPI面向短距离通信如微控制器与闪存基于单控制器多外设模型使用 COPI/CIPO/SCLK 三根主线加每外设一根 CS片选线。SPI 是全双工的通过时钟同步无需起始/停止位通常可每秒传输数 MB无线协议蓝牙主要是 BLE、LoRaWAN远距离低功耗、WiFi 等。商用土壤湿度传感器常用 LoRaWAN 将田间数据发给集线设备Zigbee 则用 WiFi 构建网状网络设备互为中继直至协调器接入互联网。传感器标定Calibration传感器测量的是电阻/电容等电气量需经标定转换为实用单位。有的传感器出厂已标定如温度传感器直接返回 °C。土壤湿度可用重量含水量gravimetric每公斤干土中水的公斤数或体积含水量volumetric每立方米干土中水的立方米数衡量。由于土壤成分会影响电气特性理想做法是把传感器读数与实验室科学测量对照绘出电压—土壤湿度曲线并拟合直线此后 IoT 设备的读数即可经该直线换算为真实土壤湿度。注意电阻式传感器电压随湿度增大而升高电容式则相反曲线下倾。硬件实测引导见 2-farm/lessons/2-detect-soil-moisture该课代码目录下包含 Wio TerminalPlatformIO C、Raspberry Pi 与虚拟设备的完整示例。第 3 课自动化植物浇水用继电器控制大功率设备IoT 设备电压很低通常提供 3.3V/5V电流小于 1A不足以驱动水泵等大功率硬件强行驱动会烧毁开发板。解决办法是让水泵接外部电源用一个执行器像开关一样控制其通断——这与手指拨动电灯开关接通 110V/240V 市电的原理相同。继电器Relay是最常用的电机械开关控制电路为电磁铁通电电磁铁吸合杠杆闭合输出电路的一组触点断电后杠杆释放、触点断开。继电器是数字执行器——高电平开启、低电平关闭。输出电路可承载远高于控制电路的功率例如 Grove 继电器输出电路最高可处理 250V/10A。接线示例中USB 电源 5V 经继电器输出电路一端接入另一端接水泵水泵再接电源地继电器闭合即向水泵供电。注意继电器存在多种类型例如上电时是接通还是断开、是否有多个输出电路杠杆吸合时通常能听到清脆的咔嗒声早期电门铃的蜂鸣器正是利用继电器快速通断发出嗡嗡声。通过 MQTT 控制植物商业灌溉系统的控制逻辑是集中式的基于多个传感器数据做决策配置只改一处。为模拟这一点课程用 MQTT 控制继电器在soil-moisture-sensor项目中加入 MQTT 库客户端 ID 为IDsoilmoisturesensor_client设备代码发送soil_moisture遥测属性新建soil-moisture-sensor-server服务端订阅遥测并下发控制命令命令消息属性为relay_on客户端 ID 为IDsoilmoisturesensor_server设备端收到命令后按relay_on属性控制继电器若soil_moisture大于 450 则发送relay_on: true否则false。完整示例见 code-mqtt。传感器与执行器的时序问题用实体传感器做过土壤湿度实验会发现浇水后读数需要几秒才下降——这不是传感器迟钝而是水渗透土壤需要时间靠近传感器浇水可能先快速下降又回升那是水分扩散的结果。同理执行器动作到传感器读数变化之间存在延迟若像小夜灯那样读数低于阈值立刻开泵、达到阈值立刻关泵水仍在继续渗透导致过浇、浪费水甚至烂根。因此最佳浇水循环应该是开启水泵 5 秒等待 20 秒让水渗透、读数稳定重新检查土壤湿度若仍高于目标值湿度仍不够重复以上步骤具体时长高度依赖你的设备、被测量属性与传感器/执行器宁可少浇还能再开泵不可多浇无法从土壤中取水。更精细的做法是每高于目标 100 就开泵 1 秒而非固定 5 秒露天种植还可结合天气预报——预报有雨则推迟浇水雨后再评估是否仍需浇。给植物控制服务端添加时序服务端逻辑为收到遥测 → 检查土壤湿度 → 若湿度不足则发命令开继电器 → 等 5 秒 → 发命令关继电器 → 等 20 秒待湿度稳定。由于遥测每 10 秒一条而整个浇水循环约 25 秒需要避免重叠触发新循环。相比把设备改为每分钟上报一次不利于大农场的水流分析更好的方案是在浇水循环期间退订遥测代码在无法处理时忽略遥测但其他订阅同一数据的服务仍可读取。完整实现见 code-timing/server/app.pywater_time 5 wait_time 20 def send_relay_command(client, state): command { relay_on : state } print(Sending message:, command) client.publish(server_command_topic, json.dumps(command)) def control_relay(client): print(Unsubscribing from telemetry) mqtt_client.unsubscribe(client_telemetry_topic) send_relay_command(client, True) time.sleep(water_time) send_relay_command(client, False) time.sleep(wait_time) print(Subscribing to telemetry) mqtt_client.subscribe(client_telemetry_topic) def handle_telemetry(client, userdata, message): payload json.loads(message.payload.decode()) print(Message received:, payload) if payload[soil_moisture] 450: threading.Thread(targetcontrol_relay, args(client,)).start()要点import threading让control_relay在后台独立线程运行避免阻塞 MQTT 消息循环退订—浇水—等待—重新订阅的模式保证了循环期间不会处理新的遥测消息。第 4 课将植物迁移到云端什么是云云常常被戏称为别人的计算机你不必自建数据中心涉及买机器、硬件维护、供电散热、网络、安全、软件安装更新等高昂成本而是按需向云服务商租用算力——需求高峰多租、低谷少租。云数据中心遍布全球一些大型中心面积可达数平方公里甚至自带发电站其规模化效应也使其比大量小型数据中心更环保。本课使用Microsoft Azure。你需要一个云订阅有两种免费方式Azure for Students18 岁以上学生无需信用卡用学校邮箱验证注册即获 US$100 额度及包含免费 IoT 服务在内的免费服务有效期 12 个月、可逐年续期Azure 免费订阅非学生需信用卡验证身份但不会扣费前 30 天有 US$200 额度及免费层服务额度用完也不会自动扣款。云 IoT 服务为什么优于公共测试 Broker之前使用的公共 MQTT broker 适合学习但在商用场景有四大缺陷可靠性免费无保障随时可能关闭、安全性公开可窃听遥测或下发恶意命令、性能仅适合少量测试消息、可发现性无法得知哪些设备在线。云 IoT 服务则具备高可靠性、内建安全、高性能可扩展并知晓所有已注册设备——未注册设备连接会被拒绝。设备通过设备 SDK或直接走 MQTT/HTTP 等协议接入应用其他组件通过服务 SDK与设备通信用 Azure CLI 创建 IoT Hub安装 Azure CLI 后添加 IoT 扩展并登录az extension add --name azure-iot az login多订阅环境下先列出并选择订阅az account list --output table az account set --subscription SubscriptionId查询可用区域本课写作时约 65 个并创建资源组az account list-locations --output table az group create --name soil-moisture-sensor --location location创建免费层 IoT Hub免费层每日 8,000 条消息每个订阅仅限一个az iot hub create --resource-group soil-moisture-sensor \ --sku F1 \ --partition-count 2 \ --name hub_name--sku F1选择免费层--partition-count 2定义 IoT Hub 支持的数据分区数创建免费层 IoT Hub 的必需参数。hub 名称需全局唯一因为它会出现在访问 URL 中。IoT Hub 的通信方式IoT Hub 定义了若干设备↔云通信机制底层可走 MQTT、HTTPS 或 AMQP设备到云D2C消息设备发往 IoT Hub 的遥测应用代码可读取底层基于 Azure Event Hubs读取时通常称为事件云到设备C2D消息应用代码经 IoT Hub 发给设备的消息直连方法请求Direct method请求设备执行动作如控制执行器必须响应以便应用代码确认处理成功设备孪生Device twins在设备与 IoT Hub 间保持同步的 JSON 文档用于存储设备上报属性或云端期望desired配置。IoT Hub 可暂存消息与直连方法请求默认一天设备离线重连后仍能取回离线期间的消息设备孪生则永久保存在 IoT Hub。注册设备并验证云端连通az iot hub device-identity create --device-id soil-moisture-sensor --hub-name hub_name az iot hub device-identity connection-string show --device-id soil-moisture-sensor \ --output table --hub-name hub_name连接字符串是含服务标识URL与密钥SharedAccessKey的文本由设备 SDK 使用——必须妥善保管。随后可监控设备遥测az iot hub monitor-events --hub-name hub_name输出中可见payload为{soil_moisture: 376}等消息加--properties anno可查看自动附加的注解annotations如iothub-connection-device-id发送方设备 ID与iothub-enqueuedtimeUNIX 时间戳等。还可以下发直连方法控制继电器az iot hub invoke-device-method --device-id soil-moisture-sensor \ --method-name relay_on \ --method-payload {} \ --hub-name hub_name设备端会打印Direct method received - relay_on。注意设备每 10 秒发一条遥测一天约 8,640 条已接近免费层 8,000 条/日的上限——课程挑战题正是思考如何调整上报频率以留在免费层内。第 5 课将应用逻辑迁移到云端什么是 ServerlessServerless无服务器计算又称 FaaS是指在云端以小块代码响应各类事件事件发生时你的代码被加载运行并传入事件数据无事发生时代码不存活。因此它天然可扩展——大量事件同时发生时云提供商会并行运行你的函数实例。代价是函数间共享信息需存到数据库等外部存储不能依赖内存。计费方式为按代码运行时间与内存用量付费不运行时零费用。对 IoT 开发者而言Serverless 是理想模型写一个响应任何已连接设备发到云 IoT 服务的消息的函数即可代码仅在需要时运行。创建 Azure Functions 应用Microsoft 的无服务器服务是Azure Functions开箱支持 Python、JavaScript、TypeScript、C#、F#、Java 与 PowerShell本课用 Python。Functions 应用由若干触发器triggers组成共享同一套配置。本地开发链路安装 Azure Functions Core Tools 与 VS Code 扩展 → 安装 Node.js → 全局安装存储模拟器npm install -g azurite mkdir azurite azurite --location azuriteAzurite 会在本地启动 Blob10000 端口、Queue10001、Table10002三个服务。然后创建项目mkdir soil-moisture-trigger cd soil-moisture-trigger python3 -m venv .venv source ./.venv/bin/activate # Linux/macOSWindows 用 .venv\Scripts\activate.bat 或 Activate.ps1 func init --worker-runtime python soil-moisture-trigger pip install -r requirements.txtfunc init会生成三个文件host.json应用级设置、local.settings.json本地运行设置如 IoT Hub 连接字符串不应提交到源码控制、requirements.txtPip 依赖。需把AzureWebJobsStorage设为UseDevelopmentStoragetrue以连接 Azurite。创建 IoT Hub 事件触发器触发器要读取 IoT Hub 的消息流需连接 IoT Hub 的Event Hub 兼容端点IoT Hub 基于 Azure Event Hubs读消息方式与 Event Hubs 相同。获取连接字符串并写入local.settings.json的Values段az iot hub connection-string show --default-eventhub --output table --hub-name hub_nameIOT_HUB_CONNECTION_STRING: connection string创建触发器没有专门的 IoT Hub 触发器模板使用 Event Hub 触发器func new --name iot-hub-trigger --template Azure Event Hub trigger生成的iot-hub-trigger文件夹包含__init__.py核心是main函数每次有消息发到 IoT Hub 即被调用import logging import azure.functions as func def main(event: func.EventHubEvent): logging.info(Python EventHub trigger processed an event: %s, event.get_body().decode(utf-8))function.json含bindings绑定配置。关键字段type: eventHubTrigger监听事件、name: events对应 Python 参数名、direction: in输入绑定、connection: 从设置读取连接字符串——不能直接写入连接字符串。因模板缺陷需手工修正三处把cardinality从many改为one否则报list object has no attribute get_body、把connection设为IOT_HUB_CONNECTION_STRING、把eventHubName清空连接字符串已含EntityPath重复指定会报错。运行func start后函数会处理过去一天内已发到 IoT Hub 的事件Functions: iot-hub-trigger: eventHubTrigger ... Python EventHub trigger processed an event: {soil_moisture:628}从 Serverless 代码下发直连方法监听之外还需向设备发命令这要通过Registry Manager注册表管理器——它管理已注册设备、可发送 C2D 消息/直连方法/更新设备孪生。用ServiceConnect策略获取连接字符串该策略允许连接并发送消息给设备遵循最小权限原则az iot hub connection-string show --policy-name service --output table --hub-name hub_name在requirements.txt中加入azure-iot-hub并pip install -r requirements.txt。改造__init__.py的main函数完整代码见 code/functionsimport json import os from azure.iot.hub import IoTHubRegistryManager from azure.iot.hub.models import CloudToDeviceMethod body json.loads(event.get_body().decode(utf-8)) device_id event.iothub_metadata[connection-device-id] soil_moisture body[soil_moisture] if soil_moisture 450: direct_method CloudToDeviceMethod(method_namerelay_on, payload{}) else: direct_method CloudToDeviceMethod(method_namerelay_off, payload{}) registry_manager_connection_string os.environ[REGISTRY_MANAGER_CONNECTION_STRING] registry_manager IoTHubRegistryManager(registry_manager_connection_string) registry_manager.invoke_device_method(device_id, direct_method)要点设备 ID 从事件的iothub_metadata[connection-device-id]注解中取出因此直连方法会发给正确的单一设备——比之前 MQTT 版广播给所有设备更适合多套传感器/继电器并存连接字符串在本地从local.settings.json读为环境变量部署后则从云端 Application Settings 读取。部署到云端创建存储账户Functions 需要少量云存储Standard_LRS为最低成本通用账户无免费层但费用很低存储最贵也不到每 GB 每月 US$0.05az storage account create --resource-group soil-moisture-sensor \ --sku Standard_LRS \ --name storage_name存储账户名需全局唯一仅限小写字母与数字最多 24 字符。创建 Functions AppPython 仅支持 Linux 托管az functionapp create --resource-group soil-moisture-sensor \ --runtime python \ --functions-version 3 \ --os-type Linux \ --consumption-plan-location location \ --storage-account storage_name \ --name functions_app_name把本地设置上传为 Application Settings部署后从环境变量读取az functionapp config appsettings set --resource-group soil-moisture-sensor \ --name functions_app_name \ --settings IOT_HUB_CONNECTION_STRINGconnection string # 同样设置 REGISTRY_MANAGER_CONNECTION_STRING发布func azure functionapp publish functions_app_name输出Deployment successful.并列出已部署的触发器iot-hub-trigger - [eventHubTrigger]即成功。此后调整土壤湿度即可看到云端逻辑自动控制继电器开关。 注意IoT Hub 触发器无法退订之前 MQTT 版浇水循环期间退订的时序策略在此不适用需要另想他法这正是课程的挑战题。第 6 课保障植物安全为什么要保护 IoT 设备IoT 安全要确保只有预期的设备能连入云 IoT 服务并发送遥测只有你的云服务能向设备发命令。不安全的代价可能是伪造设备持续上报高湿度导致灌溉永不启动、植物干死黑客操控设备长时间浇水导致烂根并造成水费损失读取个人/商业敏感数据以设备为跳板入侵内部网络甚至以个人数据勒索。历史上已有大量真实案例如鱼缸恒温器漏洞被用于入侵赌场网络、Mirai 僵尸网络利用默认口令的 IoT 设备发起大规模 DDoS 攻击、联网玩具数据库泄露儿童语音消息、健身应用暴露用户住址等。密码学基础设备用 ID 自证身份但 ID 可被克隆。解决之道是加密用只有设备与云端知晓的密钥encryption key把数据打乱成密文云端用相同或配对的解密密钥还原无法解密即视为被入侵而拒绝。早期密码学替代密码如凯撒密码按固定位移替换字母、维吉尼亚密码用单词对不同字母作不同位移现代密码学基于复杂数学密钥空间大到暴力破解不可行。HTTPS 即浏览器与服务器间加密通信的典型应用对称加密加密与解密用同一密钥发送方与接收方需共享密钥共享过程可能泄密速度快但安全性较低非对称加密公钥/私钥对。公钥用于加密可公开私钥用于解密仅持有者保留。更安全但更慢常见做法是用非对称加密安全地共享对称密钥再用对称密钥加密数据。用对称密钥保护设备连接字符串与 SAS此前连接 IoT Hub 用的连接字符串由三部分分号分隔的键值对组成HostNamesoil-moisture-sensor.azure-devices.net;DeviceIdsoil-moisture-sensor;SharedAccessKeyBhryind7kKEIDxubK61RiEHHRTrPl7HUow8cEm/mU0键值说明HostNamesoil-moisture-sensor.azure-devices.netIoT Hub 的 URLDeviceIdsoil-moisture-sensor设备唯一 IDSharedAccessKeyBhryind7kKEIDxubK61RiEHHRTrPl7HUow8cEm/mU0设备与 IoT Hub 共同持有的对称密钥密钥从不直接传输。设备首次连接时发送共享访问签名SAS令牌含 IoT Hub URL、过期时间戳通常为当前时间 1 天与签名URL过期时间用共享密钥加密。IoT Hub 用共享密钥解密签名并核对 URL 与过期时间同时验证当前时间早于过期时间防止恶意设备截获真实设备的 SAS 令牌重放。也正因有过期时间设备需要准确的时钟通常从 NTP 服务器读取时间不准会导致连接失败。 密钥不应写死在代码里代码泄露密钥泄露且发布时要为每台设备重新编译。理想做法是从硬件安全模块读取学习阶段写进代码可以但切勿提交到公开源码库。设备有 2 个密钥与 2 条对应连接字符串便于密钥轮换rotate。X.509 证书非对称加密的落地非对称加密下你需要把公钥交给发送方——但对方如何确认公钥确实属于你解决方案是X.509 证书把公钥放入由可信第三方证书颁发机构CA签发并数字签名的数字文档中。证书含持有人信息、签发 CA、有效期与公钥本身使用前应验证其确由原 CA 签发。CA 签发收费测试可自签名自己签发但生产环境绝不可用自签名证书。X.509 证书可跨设备共享创建一份证书上传到 IoT Hub所有设备共用每台设备只需知道私钥来解密来自 IoT Hub 的消息。设备用于加密发往 IoT Hub 消息的证书由微软发布与许多 Azure 服务共用甚至内置于 SDK。实战创建 X.509 设备身份Azure CLI 可一步完成生成密钥对 创建自签名证书 注册设备az iot hub device-identity create --device-id soil-moisture-sensor-x509 \ --am x509_thumbprint \ --output-dir . \ --hub-name hub_name该命令在当前目录生成两个文件soil-moisture-sensor-x509-key.pem设备私钥切勿提交到公开源码控制与soil-moisture-sensor-x509-cert.pemX.509 证书。设备侧接入引导见 single-board-computer-x509.md 与 wio-terminal-x509.md。本课是项目最后一课完成后应参照 clean-up.md 清理云端资源。课程配套资源速查整个项目贯穿理论 三套硬件路径Wio Terminal / Raspberry Pi / 虚拟设备 服务端代码的模式可在各课目录中直接查阅与运行第 1 课发布温度并落盘 CSV 的完整服务端实现 app.pyGDD 可视化作业 gdd.ipynb第 2 课三种硬件的土壤湿度测量代码 2-farm/lessons/2-detect-soil-moisture/code第 3 课MQTT 遥控继电器 code-mqtt、继电器直控 code-relay、带时序控制的浇灌服务端 app.py第 4 课三种硬件连接 IoT Hub 的接入代码 2-farm/lessons/4-migrate-your-plant-to-the-cloud/code第 5 课Azure Functions 触发器完整工程 code/functions第 6 课X.509 认证的设备代码 2-farm/lessons/6-keep-your-plant-secure/code。如果只完成部分课时而用到了云端资源务必按 clean-up.md 中的az group delete --name resource-group-name删除整个资源组以清理全部云资源、避免潜在费用。从一棵盆栽的土壤湿度监测到可部署于云端、按需灌溉整片农场的自动化系统——这 6 堂课恰好完整覆盖了数字农业 IoT 应用从原型到生产化的全链路。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

电子工程师职场生存指南:技术深度与业务理解的平衡

电子工程师职场生存指南:技术深度与业务理解的平衡

1. 电子工程师的职场生存法则作为一名从业15年的硬件老兵,我见过太多同行在技术道路上跌跌撞撞。今天要分享的这些"毒鸡汤",不是培训机构里的成功学,而是实验室里用烧坏的电路板和通宵调试换来的血泪经验。每一条都值得打印出来贴在…

📅 2026/9/15 1:18:59
Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践

Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践

Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践 【免费下载链接】notebook Jupyter Interactive Notebook 项目地址: https://gitcode.com/GitHub_Trending/no/notebook Jupyter Notebook 是一款基于 Web 的交互式计算笔记本环境&…

📅 2026/9/15 1:13:53
TanStack Router 代码路由(Code-Based Routing)完全指南:用 `createRoute` 手工构建类型安全的路由树

TanStack Router 代码路由(Code-Based Routing)完全指南:用 `createRoute` 手工构建类型安全的路由树

TanStack Router 代码路由(Code-Based Routing)完全指南:用 createRoute 手工构建类型安全的路由树 【免费下载链接】router 🤖 A client-first, server-capable, fully type-safe router and full-stack framework for the web (…

📅 2026/9/15 1:13:53
MORE NEWS

更多资讯

📰

Spring Boot 2.x 日志配置 与集成 Logback 日志框架,SQL日志记录方式汇总

目录 Spring Boot 日志依赖关系 Spring boot 全局日志设置 Spring boot Log Levels 日志级别 Spring boot Log Groups 日志记录器组 Logback 日志配置文件详解 java -jar 启动设置日志输出级别 动态切换 Logback 日志输出级别 logback.xml 配置文件定时监控 LoggerCon…

📰

NVMe SSD上电到Ready全流程时序解析

1. 从“黑屏三秒”到“盘符闪现”:一次真实上电旅程的全程解剖你有没有在工控机冷启动时盯着 BIOS 界面,看着 NVMe SSD 的识别时间比其他设备慢半拍?或者在嵌入式系统调试中,发现系统日志里nvme0n1: attached这行消息总要等上 800…

📰

高效降重实用技巧分享 助力内容原创性提升与合规性优化

搞科研的朋友都懂,找英文文献永远是科研路上第一道耗时又磨人的坎。 尤其是 2026 年的当下,顶刊新成果迭代速度翻倍,学校图书馆权限永远覆盖不全,关键词检索翻几十页都找不到匹配研究方向的核心论文;免费 OA 平台要么…

📰

IoT-For-Beginners 智慧农业实战:用 6 堂课从土壤传感器到云端物联网农场

IoT-For-Beginners 智慧农业实战:用 6 堂课从土壤传感器到云端物联网农场 【免费下载链接】IoT-For-Beginners 12 Weeks, 24 Lessons, IoT for All! 项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners 数字农业正在重塑农业生产的每一个环…

📰

电子工程师职场生存指南:技术深度与业务理解的平衡

1. 电子工程师的职场生存法则作为一名从业15年的硬件老兵,我见过太多同行在技术道路上跌跌撞撞。今天要分享的这些"毒鸡汤",不是培训机构里的成功学,而是实验室里用烧坏的电路板和通宵调试换来的血泪经验。每一条都值得打印出来贴在…

📰

Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践

Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践 【免费下载链接】notebook Jupyter Interactive Notebook 项目地址: https://gitcode.com/GitHub_Trending/no/notebook Jupyter Notebook 是一款基于 Web 的交互式计算笔记本环境&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬