| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- #!/usr/bin/env python3
- """
- DHT11 GPIO 自动探测脚本
- 在目标板子上运行,自动尝试多个候选 GPIO line,找到能成功读取 DHT11 的 pin。
- 探测成功后输出 JSON,供部署脚本读取并写入环境变量配置。
- """
- import os
- import sys
- import json
- import time
- # 把 backend 目录加入路径,以便复用 dht11_sensor 模块
- SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
- BACKEND_DIR = os.path.dirname(SCRIPT_DIR)
- sys.path.insert(0, BACKEND_DIR)
- from modules.dht11_sensor import DHT11Sensor
- # 候选 GPIO line 编号:RK3562 GPIO0_C3_d 对应 gpiochip0 line 19。
- # 如需扫描更多,可通过环境变量 DHT11_GPIO_PIN 指定一个或多个(逗号分隔)。
- DEFAULT_CANDIDATES = [19]
- def detect(gpio_pin=None, gpio_chip='gpiochip0', max_attempts=3, simulate=False):
- """
- 探测 DHT11 传感器。
- 如果 gpio_pin 给出,只尝试该 pin;否则扫描 DEFAULT_CANDIDATES。
- 返回 (pin, temperature, humidity) 或 None。
- simulate=True 用于无硬件环境测试脚本流程。
- """
- if simulate:
- sensor = DHT11Sensor(gpio_pin=gpio_pin or 0, gpio_chip=gpio_chip, simulate=True)
- temp, hum = sensor._read_simulated()
- return {
- 'gpio_pin': int(gpio_pin) if gpio_pin else 0,
- 'gpio_chip': gpio_chip,
- 'temperature': temp,
- 'humidity': hum,
- 'success': True
- }
- if gpio_pin:
- # 支持逗号分隔的多个候选,例如 "2,64,72"
- candidates = [int(p.strip()) for p in str(gpio_pin).split(',')]
- else:
- candidates = DEFAULT_CANDIDATES
- for pin in candidates:
- sensor = DHT11Sensor(gpio_pin=pin, gpio_chip=gpio_chip, simulate=False)
- for attempt in range(max_attempts):
- try:
- temp, hum = sensor._read_real()
- if temp is not None and hum is not None:
- return {
- 'gpio_pin': pin,
- 'gpio_chip': gpio_chip,
- 'temperature': temp,
- 'humidity': hum,
- 'success': True
- }
- except Exception as e:
- print(f" 探测 GPIO {pin} 失败: {e}", file=sys.stderr)
- time.sleep(2.5) # DHT11 两次读取间隔需 >2s
- return None
- def main():
- pin_env = os.getenv('DHT11_GPIO_PIN')
- chip_env = os.getenv('DHT11_GPIO_CHIP', 'gpiochip0')
- simulate = os.getenv('DHT11_SIMULATE', 'false').lower() in ('1', 'true', 'yes')
- print(f"开始探测 DHT11 (chip={chip_env}, simulate={simulate})...", file=sys.stderr)
- if pin_env:
- print(f"用户指定优先探测 GPIO: {pin_env}", file=sys.stderr)
- result = detect(gpio_pin=pin_env, gpio_chip=chip_env, simulate=simulate)
- if result:
- # 同时输出机器可读行和 JSON,方便部署脚本解析
- print(
- f"DHT11_OK pin={result['gpio_pin']} chip={result['gpio_chip']} "
- f"temp={result['temperature']} hum={result['humidity']}"
- )
- print(json.dumps(result, ensure_ascii=False))
- print(
- f"探测成功: GPIO pin={result['gpio_pin']}, "
- f"温度={result['temperature']}°C, 湿度={result['humidity']}%",
- file=sys.stderr
- )
- sys.exit(0)
- else:
- print("DHT11_FAIL")
- error = {
- 'success': False,
- 'error': '未能在任何候选 GPIO 上读取到 DHT11,请检查接线或手动指定 DHT11_GPIO_PIN',
- 'candidates': DEFAULT_CANDIDATES if not pin_env else [int(pin_env)]
- }
- print(json.dumps(error, ensure_ascii=False))
- sys.exit(1)
- if __name__ == '__main__':
- main()
|