使用此 Raspberry Pi 恒温器教程控制您的气候

已发表: 2022-03-11

许多家庭的空调缺乏中央自动化、可编程恒温器、多个传感器或 Wi-Fi 控制等现代细节。 但较旧的空调技术仍然可靠,因此在许多情况下,不太可能很快升级。

然而,这需要用户经常中断工作或睡眠来打开或关闭空调。 在布局紧凑的房屋中尤其如此,例如我的:

平面图,顶部有空调,中心右侧。它的输出必须绕两个角才能到达大多数房间,包括左下角的卧室。
我的非正统平面图使使用单个窗内空调单元进行冷却成为一项挑战。 从卧室遥控没有直接的视线,也没有冷空气到达所有房间的直接路径。

美国家庭通常有中央空调,但全球并非如此。 没有中央空调限制了自动化选项,使得在整个家庭中实现相同的温度变得更加困难。 特别是,它很难避免可能需要人工干预才能解决的温度波动。

作为一名工程师和物联网 (IoT) 爱好者,我看到了一次做一些有用的事情的机会:

  • 通过提高我的独立空调机组的效率来帮助节约能源
  • 通过自动化和 Google Home 集成让我的家更舒适
  • 完全按照我想要的方式定制我的解决方案,而不是局限于商业可用的选项
  • 使用久经考验的硬件复习我的一些专业技能

我的空调是带有简单红外遥控器的基本设备。 我知道可以使空调装置与智能家居系统一起使用的设备,例如 Sensibo 或 Tado。 相反,我采用了 DIY 方法并创建了一个 Raspberry Pi 恒温器,允许基于来自不同房间的传感器输入进行更复杂的控制。

树莓派恒温器硬件

我已经在使用几个 Raspberry Pi Zero Ws 以及 DHT22 传感器模块来监控不同房间的温度和湿度。 由于分段平面图,我安装了传感器来监测我家不同地方的温度。

我在带有 WSL 2 的 Windows 10 PC 上还有一个家庭监控系统(此项目不需要)。我想将传感器读数集成到监控视频中,作为视频源上的文本覆盖。

传感器接线

传感器接线简单,只有三个连接:

第一个连接是“VCC from sensor to PIN1 - 3v3”,第二个是“DATA from sensor to PIN7 - GPIO4”,第三个是“GND from sensor to PIN9 - GND”。
DHT22 模块的接线图,显示了用于将其连接到 Raspberry Pi 的引脚。

我使用了 Raspberry Pi OS Lite,安装了带有 PiP 的 Python 3 和用于 Python 的 Adafruit_DHT 库来读取传感器数据。 它在技术上已被弃用,但更易于安装和使用。 另外,我们的用例需要更少的资源。

我还想记录所有读数,所以我使用了第三方服务器 ThingSpeak 来托管我的数据并通过 API 调用提供服务。 它相对简单,因为我不需要实时读数,所以我选择每五分钟发送一次数据。

 import requests import time import random import Adafruit_DHT KEY = 'api key' def pushData(temp:float, hum:float): '''Takes temp and humidity and pushes to ThingsSpeak''' url = 'https://api.thingspeak.com/update' params = {'api_key': KEY, 'field5': temp, 'field6': hum} res = requests.get(url, params=params) def getData(sensor:int, pin:int): ''' Input DHT sensor type and RPi GPIO pin to collect a sample of data Parameters: sensor: Either 11 or 22, depending on sensor used (DHT11 or DHT22) pin: GPIO pin used (eg 4) ''' try: humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) return humidity, temperature except: Exception("Error reading sensor data") return False if __name__ == "__main__": sensor = 22 # Change to 11 if using DHT11 pin = 4 # I used GPIO pin 4 while True: h, t = getData(sensor, pin) pushData(t, h) time.sleep(300)

在我运行 WSL 2 的专用监控 PC 上,我设置了一个 PHP 脚本,该脚本从 ThingSpeak 获取数据,对其进行格式化,并将其写入一个简单的.txt文件中。 我的监控软件需要此.txt文件才能将其覆盖在视频流之上。

因为我已经在家里安装了一些自动化设备,包括智能灯泡和 Google Home 中的几个例程,所以我将传感器数据用作 Google Home 中的智能恒温器。 我的计划是创建一个 Google Home 例程,它可以根据室温自动打开或关闭空调,而无需用户输入。

黑色圆盘形设备的照片。
PNI SafeHome PT11IR Wi-Fi 智能遥控器。

Sensibo 和 Tado 等价格更高的一体化解决方案需要较少的技术设置,但只需花费一小部分成本,PNI SafeHome PT11IR 就可以让我使用手机控制其范围内的任意数量的红外设备。 控制应用涂鸦与 Google Home 集成。

克服 Google Home 集成问题

借助智能空调和传感器数据,我试图让 Raspberry 在 Google Home 中被识别为恒温器,但无济于事。 我能够将传感器数据发送到 Google IoT Cloud 及其 Pub/Sub 服务,但无法将其发送到 Google Home 以基于该数据创建例程。

考虑了几天后,我想到了一个新的方法。 如果我不需要将数据发送到 Google Home,该怎么办? 如果我可以在本地检查数据并向 Google Home 发送命令以打开或关闭空调怎么办? 我成功地测试了语音命令,所以这种方法看起来很有希望。

快速搜索出现了 Assistant Relay,这是一个由 Node.js 驱动的系统,它使用户能够向 Google Assistant 发送命令,只要它知道如何处理接收到的输入,用户就可以将任何东西与 Google Assistant 联系起来。

更好的是,使用 Assistant Relay,我可以通过简单地将 POST 请求发送到运行 Node.js 服务器的设备(在本例中为我的 Raspberry Pi Zero W)以及一些必需的参数来结束对 Google Assistant 的命令。 而已。 该脚本有据可查,因此我不会在这里详细介绍。

由于传感器数据已经在监控 PC 上被读取,我想我可以将请求集成到 PHP 脚本中以将内容保存在一个地方。

由于您可能没有.txt文件要求,因此您可以通过直接读取传感器数据并根据该数据通过 Assistant Relay 向 Google Assistant Service 发出命令来简化该过程。 所有这些都可以通过单个 Raspberry Pi 设备完成,无需额外的硬件。 然而,由于我已经完成了一半的工作,所以使用我所拥有的东西是有意义的。 本文中的两个脚本都可以在单机上使用; 此外,如果需要,可以用 Python 重写 PHP 脚本。

设置条件和自动化操作

我希望自动电源循环仅在夜间发生,因此我定义了我想要自动运行的时间——晚上 10 点到早上 7 点——并设置了首选温度。 确定正确的温度间隔——在不因过于频繁地循环供电而缩短空调装置的使用寿命的情况下达到舒适的范围——需要几次尝试才能做到正确。

创建传感器数据覆盖的 PHP 脚本设置为通过 cron 作业每五分钟运行一次,所以我添加的唯一内容是条件和 POST 请求。

然而,这产生了一个问题。 如果满足条件,脚本将每五分钟发送一次“打开”命令,即使空调已经打开。 这导致设备发出恼人的哔哔声,即使是在“关闭”命令下也是如此。 为了解决这个问题,我需要一种方法来读取设备的当前状态。

优雅不是优先事项,所以我制作了一个包含数组的 JSON 文件。 每当“打开”或“关闭”命令成功完成时,脚本就会将最后一个状态附加到该数组中。 这解决了冗余; 然而,特别炎热的日子或冬季过热可能会再次满足条件。 我决定在这些情况下手动覆盖就足够了。 我将在 switch 片段之前添加一个 return 作为读者的练习:

 <?php switch(true) { case $temperature > 27: turnAc('on'); break; case $temperature < 24: turnAc('off'); break; } function turnAc($status) { $command = 'turn on hallway ac'; // hallway ac is the Google Home device name for my AC if ($status == 'off') { $command = 'turn off hallway ac'; } if ($status == 'on' && checkAc() == 'on') { return; } if ($status == 'off' && checkAc() == 'off') { return; } $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'local assistant server ip', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS =>'{ "command": '.$command.', "converse": false, "user": "designated user" }', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json' ), )); $response = curl_exec($curl); curl_close($curl); $obj = null; try { $obj = json_decode($response); } catch (Exception $e) { } if (!$obj || $obj->success != true) { markAc($status == 'on' ? 'off' : 'on'); // if error, mark it as opposite status return; } markAc($status); } function markAc($status) { $file = __DIR__ . "/markAc.json"; $json = json_decode(file_get_contents($file), true); $json[] = array(date('F j, YH:i:s'), $status); $handler = fopen($file, "w") or die("Unable to open file!"); $txt = json_encode($json); fwrite($handler, $txt); fclose($handler); } function checkAc() { $file = __DIR__ . "/markAc.json"; $json = json_decode(file_get_contents($file), true); $end = array_pop($json); return $end[1]; }

这有效,但不是第一次尝试。 我必须一路弄清楚事情并根据需要进行调整。 希望凭借我的经验,您不需要做太多的事情就可以在第一时间把它做好。

Raspberry Pi 恒温器控制器的价值

我有动力将空调自动化,因为我家的非常规布局有时会导致不同房间的温度差异很大。 但是,即使对于那些没有遇到这个特殊问题的人来说,自动化加热和冷却也有好处。

世界各地的人们生活在不同的气候中,并为能源支付不同的价格(以及一天中不同时间的不同费率),因此即使是能源效率的适度改进也可以使某些地区的自动化变得值得。

此外,随着越来越多的家庭实现自动化,有理由探索使旧的耗电设备和电器(如空调、电加热器和热水器)自动化的潜力。 由于这些设备通常体积庞大、安装困难且升级成本高昂,因此许多人将在未来几年内一直使用它们。 让这些“笨”设备更智能一些,不仅可以提高舒适度和能源效率,还可以延长它们的使用寿命。


进一步阅读 Toptal 工程博客:

  • 如何构建 Raspberry Pi 服务器进行开发
  • 如何将旧智能手机重新用作遥控器