You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将本地Arduino采集的温度同步至Azure数据库并完成植物适配检测?

问题描述

我通过串口连接Arduino采集室内温度,同时在Azure上存储了记录植物适宜生长温度范围的数据库。现在需要验证当前室温是否符合数据库中植物的生长温度要求,但不清楚如何将本地采集的温度值同步至Azure并查询数据库中的温度列。目前我构想分为本地与云端两个脚本实现,但尚未掌握云端脚本上传至Azure的方法,以下是我编写的两段代码:

本地采集脚本
import datetime
import time
import serial

arduino = serial.Serial(port='COM3', baudrate=115200, timeout=.1)

def update_T():
    """
    更新显示时间和温度的标签内容
    """
    return arduino_read_T(arduino, -1)
    

def arduino_read_T(arduino, unit):
    """ 
    从Arduino读取当前温度

    :param arduino: 用于读取温度的硬件对象
    :param unit: 温度单位偏好(0=摄氏度,1=华氏度,其他值返回空文本)

    :return: f, c: 当前温度的华氏度和摄氏度数值
             txt_currentT: 用于GUI显示的温度文本
    """
    global fbefore
    global cbefore
    x = datetime.datetime.now()
    arduino.write(bytes("readT", 'utf-8'))
    time.sleep(0.05)
    value =  arduino.readline()
    try:
        value = str(value).lstrip("b'")
        value = str(value).rstrip("'")
        f, c = str(value).split(",")
    except:
        try:
            f = fbefore
            c = cbefore
        except: 
            f=65.3
            c=18.5
    fbefore=f
    cbefore=c
    if unit == 1: 
        txt_currentT = f"今日 {x.day}/{x.month}/{x.year} {x.hour}:{x.minute}:{x.second} 温度:{f}ºF"
    elif unit == 0: 
        txt_currentT = f"今日 {x.day}/{x.month}/{x.year} {x.hour}:{x.minute}:{x.second} 温度:{c}ºC"
    else: 
        txt_currentT = ""
    return float(f), float(c), txt_currentT


def arduino_write_cold(arduino):
    arduino.write(bytes("cold", 'utf-8'))


def arduino_write_hot(arduino):
    arduino.write(bytes("hot", 'utf-8'))
云端验证脚本
import pyodbc
import time

server = '...'
database = '...'
username = '...'
password = '...'   
driver= '{ODBC Driver 17 for SQL Server}'
conn =  pyodbc.connect('DRIVER='+driver+';SERVER=tcp:'+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = conn.cursor()

def db_check_temperature_cold(farenh):
    # 注意:原代码存在*SQL注入风险*,建议改用参数化查询
    cursor.execute("SELECT * FROM my_plants WHERE minTinF >= ?;", farenh) 
    row = cursor.fetchone() 
    list_of_names = []
    while row:
        list_of_names.append(row)
        row = cursor.fetchone()

    return list_of_names
    

def db_check_temperature_hot(farenh):
    # 注意:原代码存在*SQL注入风险*,建议改用参数化查询
    cursor.execute("SELECT * FROM my_plants WHERE maxTinF <= ?;", farenh) 
    row = cursor.fetchone() 
    list_of_names = []
    while row:
        list_of_names.append(row)
        row = cursor.fetchone()

    return list_of_names

currentTinF =0
currentTinC=0
text_currentT=0
while True:
    # 原代码中update_T()依赖本地Arduino,云端无法直接调用,需调整为接收本地传来的温度数据
    # currentTinF, currentTinC, text_currentT = update_T()
    
    # 示例:假设通过HTTP请求或MQTT接收本地温度
    # currentTinF = 从本地获取的华氏温度值

    too_cold = db_check_temperature_cold(currentTinF)
    too_hot = db_check_temperature_hot(currentTinF)
    
    # 云端无法直接控制本地Arduino,需将结果返回给本地脚本,由本地执行指令
    # if (too_cold): arduino_write_cold(arduino)
    # if (too_hot): arduino_write_hot(arduino)

    time.sleep(600) # 改为每10分钟执行一次
解决方案

1. 修正本地与云端的交互逻辑

当前两段脚本互相导入对方模块,在分布式场景下无法运行,需调整为:

  • 本地脚本:负责采集温度,将温度数据发送到云端服务,同时接收云端返回的验证结果,控制Arduino输出提示(cold/hot)。
  • 云端脚本:负责接收本地传来的温度数据,查询Azure数据库进行验证,将结果返回给本地。

常用交互方式:

  • HTTP请求:本地用requests库发送POST请求到云端服务,云端用Flask/FastAPI或Azure Function提供接口。
  • MQTT协议:借助Azure IoT Hub作为中间件,本地脚本作为设备发送温度数据,云端服务从Hub接收数据并处理。

2. 云端脚本的Azure部署方法

方法一:Azure Function(推荐,无服务器架构)

  1. 在Azure Portal创建HTTP触发的Function App(选择Python运行时)。
  2. 将云端脚本的核心逻辑(数据库查询)改写为Function的请求处理函数,接收本地传来的温度参数,执行查询后返回结果。
  3. 部署时将依赖的pyodbc包添加到requirements.txt中,Azure会自动安装。

方法二:Azure Virtual Machine

  1. 创建一台Azure VM(选择支持Python的镜像,如Ubuntu或Windows Server)。
  2. 通过SSH/RDP连接VM,安装Python和pyodbc依赖,上传云端脚本。
  3. 配置防火墙规则,允许本地脚本与VM的通信端口(如HTTP的80/443)。

方法三:Azure App Service

  1. 创建Web App(Python运行时),将云端脚本封装为Flask/FastAPI应用。
  2. 部署应用到App Service,配置环境变量存储数据库连接信息(避免硬编码)。

3. 数据库查询的安全性优化

原代码使用f-string拼接SQL语句,存在SQL注入风险,必须改为参数化查询:

# 错误写法(存在注入风险)
cursor.execute(f"SELECT * FROM my_plants WHERE minTinF >= {farenh};")

# 正确写法(参数化查询)
cursor.execute("SELECT * FROM my_plants WHERE minTinF >= ?;", farenh)

内容的提问来源于stack exchange,提问作者fermarx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:55:22